Skip to main content

ppt_rs/oxml/
ns.rs

1//! XML namespace handling
2
3use std::collections::HashMap;
4
5/// Represents an XML namespace
6#[derive(Debug, Clone)]
7pub struct Namespace {
8    prefix: String,
9    uri: String,
10}
11
12impl Namespace {
13    /// Create a new Namespace
14    pub fn new(prefix: &str, uri: &str) -> Self {
15        Namespace {
16            prefix: prefix.to_string(),
17            uri: uri.to_string(),
18        }
19    }
20
21    /// Get the prefix
22    pub fn prefix(&self) -> &str {
23        &self.prefix
24    }
25
26    /// Get the URI
27    pub fn uri(&self) -> &str {
28        &self.uri
29    }
30}
31
32/// Namespace registry
33pub struct NamespaceRegistry {
34    namespaces: HashMap<String, String>,
35}
36
37impl NamespaceRegistry {
38    /// Create a new NamespaceRegistry
39    pub fn new() -> Self {
40        let mut namespaces = HashMap::new();
41
42        // Register standard namespaces
43        namespaces.insert(
44            "p".to_string(),
45            "http://schemas.openxmlformats.org/presentationml/2006/main".to_string(),
46        );
47        namespaces.insert(
48            "a".to_string(),
49            "http://schemas.openxmlformats.org/drawingml/2006/main".to_string(),
50        );
51        namespaces.insert(
52            "r".to_string(),
53            "http://schemas.openxmlformats.org/officeDocument/2006/relationships".to_string(),
54        );
55        namespaces.insert(
56            "rel".to_string(),
57            "http://schemas.openxmlformats.org/package/2006/relationships".to_string(),
58        );
59        namespaces.insert(
60            "c".to_string(),
61            "http://schemas.openxmlformats.org/drawingml/2006/chart".to_string(),
62        );
63
64        NamespaceRegistry { namespaces }
65    }
66
67    /// Register a namespace
68    pub fn register(&mut self, prefix: &str, uri: &str) {
69        self.namespaces.insert(prefix.to_string(), uri.to_string());
70    }
71
72    /// Get a namespace URI by prefix
73    pub fn get(&self, prefix: &str) -> Option<&str> {
74        self.namespaces.get(prefix).map(|s| s.as_str())
75    }
76
77    /// Get all namespaces
78    pub fn all(&self) -> &HashMap<String, String> {
79        &self.namespaces
80    }
81}
82
83impl Default for NamespaceRegistry {
84    fn default() -> Self {
85        Self::new()
86    }
87}
88
89// Standard namespace constants
90pub const PML: &str = "http://schemas.openxmlformats.org/presentationml/2006/main";
91pub const DML: &str = "http://schemas.openxmlformats.org/drawingml/2006/main";
92pub const RELATIONSHIPS: &str =
93    "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
94pub const PACKAGE_RELATIONSHIPS: &str =
95    "http://schemas.openxmlformats.org/package/2006/relationships";
96pub const CHART: &str = "http://schemas.openxmlformats.org/drawingml/2006/chart";
97pub const CORE_PROPERTIES: &str =
98    "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    #[test]
105    fn test_namespace_creation() {
106        let ns = Namespace::new("p", PML);
107        assert_eq!(ns.prefix(), "p");
108        assert_eq!(ns.uri(), PML);
109    }
110
111    #[test]
112    fn test_namespace_clone() {
113        let ns1 = Namespace::new("a", DML);
114        let ns2 = ns1.clone();
115        assert_eq!(ns1.prefix(), ns2.prefix());
116        assert_eq!(ns1.uri(), ns2.uri());
117    }
118
119    #[test]
120    fn test_registry_new() {
121        let registry = NamespaceRegistry::new();
122        assert!(registry.get("p").is_some());
123        assert!(registry.get("a").is_some());
124        assert!(registry.get("r").is_some());
125        assert!(registry.get("c").is_some());
126    }
127
128    #[test]
129    fn test_registry_default() {
130        let registry = NamespaceRegistry::default();
131        assert_eq!(registry.get("p"), Some(PML));
132        assert_eq!(registry.get("a"), Some(DML));
133    }
134
135    #[test]
136    fn test_registry_get() {
137        let registry = NamespaceRegistry::new();
138        assert_eq!(registry.get("p"), Some(PML));
139        assert_eq!(registry.get("a"), Some(DML));
140        assert_eq!(registry.get("r"), Some(RELATIONSHIPS));
141        assert_eq!(registry.get("c"), Some(CHART));
142        assert_eq!(registry.get("unknown"), None);
143    }
144
145    #[test]
146    fn test_registry_register() {
147        let mut registry = NamespaceRegistry::new();
148        registry.register("custom", "http://example.com/custom");
149        assert_eq!(registry.get("custom"), Some("http://example.com/custom"));
150    }
151
152    #[test]
153    fn test_registry_all() {
154        let registry = NamespaceRegistry::new();
155        let all = registry.all();
156        assert!(all.len() >= 5);
157        assert!(all.contains_key("p"));
158        assert!(all.contains_key("a"));
159    }
160
161    #[test]
162    fn test_namespace_constants() {
163        assert!(PML.contains("presentationml"));
164        assert!(DML.contains("drawingml"));
165        assert!(RELATIONSHIPS.contains("relationships"));
166        assert!(CHART.contains("chart"));
167        assert!(CORE_PROPERTIES.contains("core-properties"));
168    }
169
170    #[test]
171    fn test_registry_override() {
172        let mut registry = NamespaceRegistry::new();
173        let original = registry.get("p").unwrap().to_string();
174        registry.register("p", "http://custom.com/pml");
175        assert_eq!(registry.get("p"), Some("http://custom.com/pml"));
176        assert_ne!(registry.get("p"), Some(original.as_str()));
177    }
178}