1use crate::capability::Capability;
6use crate::error::{Error, Result};
7use crate::paths::metadata_path;
8use crate::registry::service_def::AuthKind;
9
10#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
17pub struct Metadata {
18 pub registry: String,
19 #[serde(default, skip_serializing_if = "Option::is_none")]
20 pub url: Option<String>,
21 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub auth: Option<AuthKind>,
24 #[serde(default, skip_serializing_if = "Vec::is_empty")]
29 pub provides: Vec<Capability>,
30 #[serde(default, skip_serializing_if = "is_false")]
37 pub backup_enabled: bool,
38}
39
40fn is_false(b: &bool) -> bool {
41 !b
42}
43
44pub fn load_metadata(service_name: &str) -> Result<Option<Metadata>> {
48 let path = metadata_path(service_name)?;
49 if !path.exists() {
50 return Ok(None);
51 }
52 let content = std::fs::read_to_string(&path).map_err(|source| Error::FileRead {
53 path: path.clone(),
54 source,
55 })?;
56 let meta: Metadata = toml::from_str(&content).map_err(|source| Error::TomlParse {
57 path: path.clone(),
58 source,
59 })?;
60 Ok(Some(meta))
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn backup_enabled_defaults_false_on_legacy_metadata() {
69 let toml_src = r#"
71registry = "bundled"
72"#;
73 let meta: Metadata = toml::from_str(toml_src).expect("parse");
74 assert!(!meta.backup_enabled);
75 }
76
77 #[test]
78 fn backup_enabled_round_trips() {
79 let meta = Metadata {
80 registry: "bundled".into(),
81 url: None,
82 auth: None,
83 provides: vec![],
84 backup_enabled: true,
85 };
86 let text = toml::to_string(&meta).expect("serialize");
87 assert!(
88 text.contains("backup_enabled = true"),
89 "serialized form: {text}"
90 );
91 let parsed: Metadata = toml::from_str(&text).expect("parse");
92 assert!(parsed.backup_enabled);
93 }
94
95 #[test]
96 fn backup_enabled_false_is_omitted_from_serialization() {
97 let meta = Metadata {
100 registry: "bundled".into(),
101 url: None,
102 auth: None,
103 provides: vec![],
104 backup_enabled: false,
105 };
106 let text = toml::to_string(&meta).expect("serialize");
107 assert!(!text.contains("backup_enabled"), "got: {text}");
108 }
109}