use crate::prelude::*;
use std::collections::HashMap;
pub struct MetaGroup<'a> {
pub(crate) esi: &'a Esi,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
pub enum HttpMethod {
#[serde(rename = "GET")]
Get,
#[serde(rename = "POST")]
Post,
#[serde(rename = "PUT")]
Put,
#[serde(rename = "DELETE")]
Delete,
#[serde(other)]
Unrecognized,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ChangeType {
Breaking,
Changed,
New,
Removed,
#[serde(other)]
Unrecognized,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
pub enum RouteHealth {
Unknown,
#[serde(rename = "OK")]
Ok,
Degraded,
Down,
Recovering,
#[serde(other)]
Unrecognized,
}
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[allow(missing_docs)]
pub struct CompatibilityDates {
pub compatibility_dates: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[allow(missing_docs)]
pub struct ChangelogEntry {
pub compatibility_date: String,
pub description: String,
pub method: HttpMethod,
pub path: String,
#[serde(rename = "type")]
pub change_type: ChangeType,
}
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[allow(missing_docs)]
pub struct Changelog {
pub changelog: HashMap<String, Vec<ChangelogEntry>>,
}
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[allow(missing_docs)]
pub struct ApiNameEntry {
pub date: String,
pub name: String,
}
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[allow(missing_docs)]
pub struct ApiName {
pub current: String,
pub history: Vec<ApiNameEntry>,
}
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[allow(missing_docs)]
pub struct RouteStatus {
pub method: HttpMethod,
pub path: String,
pub status: RouteHealth,
}
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[allow(missing_docs)]
pub struct ApiStatus {
pub routes: Vec<RouteStatus>,
}
impl MetaGroup<'_> {
api_get!(
get_changelog,
"GetMetaChangelog",
RequestType::Public,
Changelog,
);
api_get!(
get_compatibility_dates,
"GetMetaCompatibilityDates",
RequestType::Public,
CompatibilityDates,
);
api_get!(
get_name,
"GetMetaName",
RequestType::Public,
ApiName,
);
api_get!(
get_status,
"GetMetaStatus",
RequestType::Public,
ApiStatus,
);
}
#[cfg(test)]
mod tests {
use super::{
ApiName, ApiStatus, ChangeType, Changelog, CompatibilityDates, HttpMethod, RouteHealth,
};
#[test]
fn test_parse_compatibility_dates() {
let json = r#"{"compatibility_dates":["2026-08-18","2020-01-01"]}"#;
let dates: CompatibilityDates = serde_json::from_str(json).unwrap();
assert_eq!(dates.compatibility_dates.len(), 2);
}
#[test]
fn test_parse_changelog() {
let json = r#"{"changelog":{"2026-08-18":[{"method":"GET","path":"/status","compatibility_date":"2026-08-18","type":"changed","description":"Updated."}]}}"#;
let log: Changelog = serde_json::from_str(json).unwrap();
assert_eq!(
log.changelog["2026-08-18"][0].change_type,
ChangeType::Changed
);
assert_eq!(log.changelog["2026-08-18"][0].method, HttpMethod::Get);
}
#[test]
fn test_parse_name_and_status() {
let name: ApiName = serde_json::from_str(
r#"{"current":"ESI","history":[{"date":"2026-01-01","name":"Old"}]}"#,
)
.unwrap();
assert_eq!(name.history[0].name, "Old");
let status: ApiStatus =
serde_json::from_str(r#"{"routes":[{"method":"GET","path":"/status","status":"OK"}]}"#)
.unwrap();
assert_eq!(status.routes[0].status, RouteHealth::Ok);
}
}