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( &self, request: T, ) -> anyhow::Result { self .post( "/auth", json!({ "type": T::req_type(), "params": request }), ) .await } pub async fn read( &self, request: T, ) -> anyhow::Result { self .post( "/read", json!({ "type": T::req_type(), "params": request }), ) .await } pub async fn write( &self, request: T, ) -> anyhow::Result { self .post( "/write", json!({ "type": T::req_type(), "params": request }), ) .await } pub async fn execute( &self, request: T, ) -> anyhow::Result { self .post( "/execute", json!({ "type": T::req_type(), "params": request }), ) .await } async fn post( &self, endpoint: &str, body: impl Into>, ) -> anyhow::Result { 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:#?}")), } } } }