polyoxide_data/api/
health.rs1use polyoxide_core::{HttpClient, Request, RequestError};
2use serde::{Deserialize, Serialize};
3use std::time::{Duration, Instant};
4
5use crate::error::DataApiError;
6
7#[derive(Clone)]
9pub struct Health {
10 pub(crate) http_client: HttpClient,
11}
12
13impl Health {
14 pub async fn check(&self) -> Result<HealthResponse, DataApiError> {
16 Request::<HealthResponse, DataApiError>::new(self.http_client.clone(), "/")
17 .send()
18 .await
19 }
20
21 pub async fn ping(&self) -> Result<Duration, DataApiError> {
38 self.http_client.acquire_rate_limit("/", None).await;
39
40 let start = Instant::now();
41 let response = self
42 .http_client
43 .client
44 .get(self.http_client.base_url.clone())
45 .send()
46 .await?;
47 let latency = start.elapsed();
48
49 if !response.status().is_success() {
50 return Err(DataApiError::from_response(response).await);
51 }
52
53 Ok(latency)
54 }
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct HealthResponse {
60 pub data: String,
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn deserialize_health_response() {
70 let json = r#"{"data": "OK"}"#;
71 let health: HealthResponse = serde_json::from_str(json).unwrap();
72 assert_eq!(health.data, "OK");
73 }
74
75 #[test]
76 fn health_response_roundtrip() {
77 let original = HealthResponse {
78 data: "OK".to_string(),
79 };
80 let json = serde_json::to_string(&original).unwrap();
81 let deserialized: HealthResponse = serde_json::from_str(&json).unwrap();
82 assert_eq!(deserialized.data, original.data);
83 }
84}