lexicon_spec/
ecosystem.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7pub struct EcosystemManifest {
8 pub name: String,
10
11 #[serde(default)]
13 pub repos: Vec<RepoEntry>,
14
15 #[serde(default)]
17 pub shared_contracts: Vec<String>,
18
19 #[serde(default)]
21 pub governance_rules: Vec<String>,
22}
23
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
26pub struct RepoEntry {
27 pub name: String,
29
30 pub path: String,
32
33 pub role: RepoRole,
35
36 #[serde(default)]
38 pub description: String,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
43#[serde(rename_all = "lowercase")]
44pub enum RepoRole {
45 Platform,
47 Service,
49 Library,
51 Tool,
53 Infrastructure,
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn test_ecosystem_manifest_serde_roundtrip() {
63 let manifest = EcosystemManifest {
64 name: "acme-platform".into(),
65 repos: vec![
66 RepoEntry {
67 name: "acme-core".into(),
68 path: "../acme-core".into(),
69 role: RepoRole::Platform,
70 description: "Core platform services".into(),
71 },
72 RepoEntry {
73 name: "acme-auth".into(),
74 path: "../acme-auth".into(),
75 role: RepoRole::Service,
76 description: "Authentication service".into(),
77 },
78 ],
79 shared_contracts: vec!["api-versioning".into()],
80 governance_rules: vec!["all repos must pass conformance checks".into()],
81 };
82
83 let toml_str = toml::to_string_pretty(&manifest).unwrap();
84 let back: EcosystemManifest = toml::from_str(&toml_str).unwrap();
85 assert_eq!(manifest, back);
86 }
87
88 #[test]
89 fn test_ecosystem_manifest_defaults() {
90 let toml_str = r#"
91 name = "my-ecosystem"
92 "#;
93 let manifest: EcosystemManifest = toml::from_str(toml_str).unwrap();
94 assert_eq!(manifest.name, "my-ecosystem");
95 assert!(manifest.repos.is_empty());
96 assert!(manifest.shared_contracts.is_empty());
97 assert!(manifest.governance_rules.is_empty());
98 }
99
100 #[test]
101 fn test_repo_role_serde() {
102 for role in [
103 RepoRole::Platform,
104 RepoRole::Service,
105 RepoRole::Library,
106 RepoRole::Tool,
107 RepoRole::Infrastructure,
108 ] {
109 let json = serde_json::to_string(&role).unwrap();
110 let back: RepoRole = serde_json::from_str(&json).unwrap();
111 assert_eq!(role, back);
112 }
113 }
114
115 #[test]
116 fn test_repo_entry_toml_roundtrip() {
117 let entry = RepoEntry {
118 name: "my-tool".into(),
119 path: "/opt/tools/my-tool".into(),
120 role: RepoRole::Tool,
121 description: "Internal developer tool".into(),
122 };
123
124 let toml_str = toml::to_string_pretty(&entry).unwrap();
125 let back: RepoEntry = toml::from_str(&toml_str).unwrap();
126 assert_eq!(entry, back);
127 }
128}