rust_rcs_core/cpim/
cpim_namespace.rs1use std::borrow::Cow;
16use std::collections::BTreeMap;
17
18use crate::internet::header::Header;
19
20pub struct CPIMNamespace {
21 registered_namespaces: BTreeMap<Vec<u8>, Vec<u8>>,
22}
23
24impl<'r> CPIMNamespace {
25 pub fn new() -> CPIMNamespace {
26 CPIMNamespace {
27 registered_namespaces: BTreeMap::new(),
28 }
29 }
30
31 pub fn register(&mut self, n: &[u8], v: &[u8]) {
32 let n = n.to_vec();
33 let v = v.to_vec();
34 self.registered_namespaces.insert(n, v);
35 }
36
37 pub fn as_inflator(&'r self) -> Box<dyn Fn(&Header) -> (Vec<u8>, &[u8]) + 'r> {
38 Box::new(|header| {
39 let mut iter = header.get_name().iter();
40 if let Some(position) = iter.position(|c| *c == b'.') {
41 for (k, v) in &self.registered_namespaces {
42 if &header.get_name()[..position] == k {
43 let mut inflated = b"<".to_vec();
44 inflated.extend(v);
45 inflated.extend(b">.");
46 inflated.extend(iter);
47 return (inflated, header.get_value());
48 }
49 }
50 }
51
52 (header.get_name().to_vec(), header.get_value())
53 })
54 }
55
56 pub fn as_deflator(&'r self) -> Box<dyn Fn(&Header) -> (Option<Header>, Cow<Header>) + 'r> {
57 Box::new(|header| {
58 for (k, v) in &self.registered_namespaces {
59 if header.get_name().starts_with(k) {
60 if k.len() < header.get_name().len() {
61 if header.get_name()[k.len()] == b'.' {
62 let mut ns = k.clone();
63 ns.extend(b"<");
64 ns.extend_from_slice(header.get_name());
65 ns.extend(b">");
66 let h1 = Header::new(b"NS", ns);
67 let mut deflated = v.clone();
68 if k.len() == 0 {
69 deflated.extend(b".");
70 deflated.extend_from_slice(header.get_name());
71 } else {
72 deflated.extend_from_slice(&header.get_name()[..k.len()]);
73 }
74 let h2 = Header::new(deflated, header.get_value().to_vec());
75 return (Some(h1), Cow::Owned(h2));
76 }
77 }
78 }
79 }
80
81 (None, Cow::Borrowed(header))
82 })
83 }
84}