Skip to main content

clayers_spec/
namespace.rs

1//! All clayers namespace URIs and prefix mappings.
2
3pub 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
22// External standard namespaces (non-layer, used for XMI/UML model integration)
23pub 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
28/// All 17 layer URN constants (excluding combined).
29pub 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
49/// Prefix-to-URI mapping for all namespaces (22 total: 17 layers + combined + 4 external).
50pub 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/// Get the prefix for a given namespace URI.
76#[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/// Get the URI for a given prefix.
82#[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        // Also check COMBINED is distinct from all layers
102        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}