clayers_spec/
namespace.rs1pub const SPEC: &str = "urn:clayers:spec";
4pub const INDEX: &str = "urn:clayers:index";
5pub const REVISION: &str = "urn:clayers:revision";
6pub const PROSE: &str = "urn:clayers:prose";
7pub const TERMINOLOGY: &str = "urn:clayers:terminology";
8pub const ORGANIZATION: &str = "urn:clayers:organization";
9pub const RELATION: &str = "urn:clayers:relation";
10pub const DECISION: &str = "urn:clayers:decision";
11pub const SOURCE: &str = "urn:clayers:source";
12pub const PLAN: &str = "urn:clayers:plan";
13pub const ARTIFACT: &str = "urn:clayers:artifact";
14pub const LLM: &str = "urn:clayers:llm";
15pub const PYTHON: &str = "urn:clayers:python";
16pub const VCS: &str = "urn:clayers:vcs";
17pub const CONTENT: &str = "urn:clayers:content";
18pub const TESTING: &str = "urn:clayers:testing";
19pub const LAYER: &str = "urn:clayers:layer";
20pub const COMBINED: &str = "urn:clayers:combined";
21
22pub const XMI: &str = "http://www.omg.org/spec/XMI/20131001";
24pub const UML: &str = "http://www.omg.org/spec/UML/20131001";
25pub const XML: &str = "http://www.w3.org/XML/1998/namespace";
26pub const XSI: &str = "http://www.w3.org/2001/XMLSchema-instance";
27
28pub const ALL_LAYERS: &[&str] = &[
30 SPEC,
31 INDEX,
32 REVISION,
33 PROSE,
34 TERMINOLOGY,
35 ORGANIZATION,
36 RELATION,
37 DECISION,
38 SOURCE,
39 PLAN,
40 ARTIFACT,
41 LLM,
42 PYTHON,
43 VCS,
44 CONTENT,
45 TESTING,
46 LAYER,
47];
48
49pub const PREFIX_MAP: &[(&str, &str)] = &[
51 ("spec", SPEC),
52 ("idx", INDEX),
53 ("rev", REVISION),
54 ("pr", PROSE),
55 ("trm", TERMINOLOGY),
56 ("org", ORGANIZATION),
57 ("rel", RELATION),
58 ("dec", DECISION),
59 ("src", SOURCE),
60 ("pln", PLAN),
61 ("art", ARTIFACT),
62 ("llm", LLM),
63 ("py", PYTHON),
64 ("vcs", VCS),
65 ("cnt", CONTENT),
66 ("tst", TESTING),
67 ("lyr", LAYER),
68 ("cmb", COMBINED),
69 ("xmi", XMI),
70 ("uml", UML),
71 ("xml", XML),
72 ("xsi", XSI),
73];
74
75#[must_use]
77pub fn prefix_for(uri: &str) -> Option<&'static str> {
78 PREFIX_MAP.iter().find(|(_, u)| *u == uri).map(|(p, _)| *p)
79}
80
81#[must_use]
83pub fn uri_for(prefix: &str) -> Option<&'static str> {
84 PREFIX_MAP
85 .iter()
86 .find(|(p, _)| *p == prefix)
87 .map(|(_, u)| *u)
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93 use std::collections::HashSet;
94
95 #[test]
96 fn all_layer_urns_are_distinct() {
97 let mut seen = HashSet::new();
98 for urn in ALL_LAYERS {
99 assert!(seen.insert(urn), "duplicate URN: {urn}");
100 }
101 assert!(!seen.contains(&COMBINED));
103 }
104
105 #[test]
106 fn prefix_map_covers_all_layers_plus_combined() {
107 let map_uris: HashSet<&str> = PREFIX_MAP.iter().map(|(_, u)| *u).collect();
108 for urn in ALL_LAYERS {
109 assert!(map_uris.contains(urn), "prefix map missing {urn}");
110 }
111 assert!(map_uris.contains(COMBINED));
112 assert_eq!(PREFIX_MAP.len(), 22);
113 }
114
115 #[test]
116 fn prefix_for_known_uri() {
117 assert_eq!(prefix_for(SPEC), Some("spec"));
118 assert_eq!(prefix_for(TERMINOLOGY), Some("trm"));
119 assert_eq!(prefix_for(COMBINED), Some("cmb"));
120 }
121
122 #[test]
123 fn uri_for_known_prefix() {
124 assert_eq!(uri_for("spec"), Some(SPEC));
125 assert_eq!(uri_for("trm"), Some(TERMINOLOGY));
126 assert_eq!(uri_for("cmb"), Some(COMBINED));
127 }
128}