Files
komodo/client/rs/src/request.rs
2024-01-08 03:07:27 -08:00

107 lines
2.3 KiB
Rust

use anyhow::{anyhow, Context};
use reqwest::StatusCode;
use serde::{de::DeserializeOwned, Serialize};
use serde_json::json;
use serror::deserialize_error;
use crate::{
api::{
auth::MonitorAuthRequest, execute::MonitorExecuteRequest,
read::MonitorReadRequest, write::MonitorWriteRequest,
},
MonitorClient,
};
impl MonitorClient {
pub async fn auth<T: MonitorAuthRequest>(
&self,
request: T,
) -> anyhow::Result<T::Response> {
self
.post(
"/auth",
json!({
"type": T::req_type(),
"params": request
}),
)
.await
}
pub async fn read<T: MonitorReadRequest>(
&self,
request: T,
) -> anyhow::Result<T::Response> {
self
.post(
"/read",
json!({
"type": T::req_type(),
"params": request
}),
)
.await
}
pub async fn write<T: MonitorWriteRequest>(
&self,
request: T,
) -> anyhow::Result<T::Response> {
self
.post(
"/write",
json!({
"type": T::req_type(),
"params": request
}),
)
.await
}
pub async fn execute<T: MonitorExecuteRequest>(
&self,
request: T,
) -> anyhow::Result<T::Response> {
self
.post(
"/execute",
json!({
"type": T::req_type(),
"params": request
}),
)
.await
}
async fn post<B: Serialize, R: DeserializeOwned>(
&self,
endpoint: &str,
body: impl Into<Option<B>>,
) -> anyhow::Result<R> {
let req = self
.reqwest
.post(format!("{}{endpoint}", self.address))
.header("x-api-key", &self.key)
.header("x-api-secret", &self.secret);
let req = if let Some(body) = body.into() {
req.header("Content-Type", "application/json").json(&body)
} else {
req
};
let res =
req.send().await.context("failed to reach monitor api")?;
let status = res.status();
if status == StatusCode::OK {
match res.json().await {
Ok(res) => Ok(res),
Err(e) => Err(anyhow!("{status} | {e:#?}")),
}
} else {
match res.text().await {
Ok(res) => Err(deserialize_error(res).context(status)),
Err(e) => Err(anyhow!("{status} | {e:#?}")),
}
}
}
}