use crate::client::Client;
use crate::errors::Error;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PingResponse {
pub message: String,
pub version: Option<String>,
pub timestamp: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceInfo {
pub timestamp: Option<String>,
pub api_version: Option<String>,
pub message: Option<String>,
pub headers: HashMap<String, String>,
}
pub async fn get_service_info() -> Result<ServiceInfo, Error> {
let client = Client::from_global_config()?;
let response = client.get_text("ping").await?;
let mut headers = HashMap::new();
for (name, value) in response.headers.iter() {
if let Ok(value_str) = value.to_str() {
headers.insert(name.to_string(), value_str.to_string());
}
}
let api_version = headers
.get("keygen-version")
.or_else(|| headers.get("x-api-version"))
.or_else(|| headers.get("api-version"))
.cloned();
let timestamp = headers
.get("date")
.or_else(|| headers.get("x-timestamp"))
.cloned();
let message = Some(response.body.trim().to_string());
Ok(ServiceInfo {
timestamp,
api_version,
message,
headers,
})
}
pub fn supports_feature(service_info: &ServiceInfo, required_version: &str) -> bool {
if let Some(version) = &service_info.api_version {
version.as_str() >= required_version
} else {
true
}
}
pub async fn ping() -> Result<PingResponse, Error> {
let client = Client::from_global_config()?;
let response = client.get_text("ping").await?;
let message = response.body.trim().to_string();
let version = response
.headers
.get("keygen-version")
.and_then(|v| v.to_str().ok())
.map(|s| s.to_string());
let timestamp = response
.headers
.get("date")
.and_then(|v| v.to_str().ok())
.map(|s| s.to_string());
Ok(PingResponse {
message,
version,
timestamp,
})
}
pub async fn supports_product_code() -> Result<bool, Error> {
let service_info = get_service_info().await?;
Ok(supports_feature(&service_info, "1.8"))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_supports_feature() {
let service_info = ServiceInfo {
timestamp: None,
api_version: Some("1.8.0".to_string()),
message: None,
headers: HashMap::new(),
};
assert!(supports_feature(&service_info, "1.7"));
assert!(supports_feature(&service_info, "1.8"));
assert!(!supports_feature(&service_info, "1.9"));
}
}