use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ServiceStatus {
Running,
Available,
Absent,
Degraded,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ServiceLifecycle {
#[default]
Daemon,
OnDemand,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceInfo {
pub id: String,
pub display_name: String,
pub status: ServiceStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hint: Option<String>,
#[serde(default)]
pub lifecycle: ServiceLifecycle,
}
pub trait ServiceConnector: Send + Sync {
fn id(&self) -> &'static str;
fn display_name(&self) -> &'static str;
fn lifecycle(&self) -> ServiceLifecycle {
ServiceLifecycle::Daemon
}
fn detect(&self) -> ServiceInfo;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn service_status_serialises_to_lowercase_strings() {
assert_eq!(
serde_json::to_value(ServiceStatus::Running).unwrap(),
serde_json::json!("running"),
"Running must serialise to \"running\""
);
assert_eq!(
serde_json::to_value(ServiceStatus::Available).unwrap(),
serde_json::json!("available"),
"Available must serialise to \"available\""
);
assert_eq!(
serde_json::to_value(ServiceStatus::Absent).unwrap(),
serde_json::json!("absent"),
"Absent must serialise to \"absent\""
);
assert_eq!(
serde_json::to_value(ServiceStatus::Degraded).unwrap(),
serde_json::json!("degraded"),
"Degraded must serialise to \"degraded\""
);
}
#[test]
fn service_lifecycle_serialises_to_snake_case() {
assert_eq!(
serde_json::to_value(ServiceLifecycle::Daemon).unwrap(),
serde_json::json!("daemon")
);
assert_eq!(
serde_json::to_value(ServiceLifecycle::OnDemand).unwrap(),
serde_json::json!("on_demand")
);
let legacy: ServiceInfo = serde_json::from_value(serde_json::json!({
"id": "trusty-search",
"display_name": "Trusty Search",
"status": "available",
}))
.expect("a payload predating #6416 must still deserialise");
assert_eq!(legacy.lifecycle, ServiceLifecycle::Daemon);
}
}