use crate::capability::Capability;
use crate::error::{Error, Result};
use crate::paths::metadata_path;
use crate::registry::service_def::{AuthKind, Runtime};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Metadata {
pub registry: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub auth: Option<AuthKind>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub provides: Vec<Capability>,
#[serde(default, skip_serializing_if = "is_false")]
pub backup_enabled: bool,
#[serde(default = "default_true", skip_serializing_if = "is_true")]
pub smtp_enabled: bool,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub enabled_groups: Vec<String>,
#[serde(default, skip_serializing_if = "Runtime::is_podman")]
pub runtime: Runtime,
}
fn is_false(b: &bool) -> bool {
!b
}
fn is_true(b: &bool) -> bool {
*b
}
fn default_true() -> bool {
true
}
pub fn load_metadata(service_name: &str) -> Result<Option<Metadata>> {
let path = metadata_path(service_name)?;
if !path.exists() {
return Ok(None);
}
let content = std::fs::read_to_string(&path).map_err(|source| Error::FileRead {
path: path.clone(),
source,
})?;
let meta: Metadata = toml::from_str(&content).map_err(|source| Error::TomlParse {
path: path.clone(),
source,
})?;
Ok(Some(meta))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn backup_enabled_defaults_false_on_legacy_metadata() {
let toml_src = r#"
registry = "default"
"#;
let meta: Metadata = toml::from_str(toml_src).expect("parse");
assert!(!meta.backup_enabled);
}
#[test]
fn backup_enabled_round_trips() {
let meta = Metadata {
registry: "default".into(),
url: None,
auth: None,
provides: vec![],
backup_enabled: true,
smtp_enabled: true,
enabled_groups: vec![],
runtime: Default::default(),
};
let text = toml::to_string(&meta).expect("serialize");
assert!(
text.contains("backup_enabled = true"),
"serialized form: {text}"
);
let parsed: Metadata = toml::from_str(&text).expect("parse");
assert!(parsed.backup_enabled);
}
#[test]
fn backup_enabled_false_is_omitted_from_serialization() {
let meta = Metadata {
registry: "default".into(),
url: None,
auth: None,
provides: vec![],
backup_enabled: false,
smtp_enabled: true,
enabled_groups: vec![],
runtime: Default::default(),
};
let text = toml::to_string(&meta).expect("serialize");
assert!(!text.contains("backup_enabled"), "got: {text}");
}
}