oca_bundle_semantics/state/oca/overlay/
meta.rs

1use crate::state::{attribute::Attribute, oca::OCABox, oca::Overlay};
2use isolang::Language;
3use oca_ast_semantics::ast::OverlayType;
4use said::derivation::HashFunctionCode;
5use said::{sad::SerializationFormats, sad::SAD};
6use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer};
7use std::any::Any;
8use std::collections::HashMap;
9
10pub trait Metas {
11    fn add_meta(&mut self, language: Language, key: String, value: String);
12}
13
14impl Metas for OCABox {
15    fn add_meta(&mut self, l: Language, key: String, value: String) {
16        match &mut self.meta {
17            Some(ref mut meta) => match meta.get_mut(&l) {
18                Some(attr_pairs) => {
19                    attr_pairs.insert(key, value);
20                }
21                None => {
22                    let mut attr_pairs = HashMap::new();
23                    attr_pairs.insert(key, value);
24                    meta.insert(l, attr_pairs);
25                }
26            },
27            None => {
28                let meta = HashMap::new();
29                self.meta = Some(meta);
30                self.add_meta(l, key, value);
31            }
32        };
33    }
34}
35
36pub fn serialize_attributes<S>(
37    attributes: &HashMap<String, String>,
38    s: S,
39) -> Result<S::Ok, S::Error>
40where
41    S: Serializer,
42{
43    use std::collections::BTreeMap;
44
45    let mut ser = s.serialize_map(Some(attributes.len()))?;
46    let sorted_attributes: BTreeMap<_, _> = attributes.iter().collect();
47    for (k, v) in sorted_attributes {
48        ser.serialize_entry(k, v)?;
49    }
50    ser.end()
51}
52
53#[derive(SAD, Serialize, Deserialize, Debug, Clone)]
54pub struct MetaOverlay {
55    #[said]
56    #[serde(rename = "d")]
57    said: Option<said::SelfAddressingIdentifier>,
58    capture_base: Option<said::SelfAddressingIdentifier>,
59    #[serde(rename = "type")]
60    overlay_type: OverlayType,
61    pub language: Language,
62    #[serde(flatten, serialize_with = "serialize_attributes")]
63    pub attr_pairs: HashMap<String, String>,
64}
65
66// TODO: why Overlay implements fn which are not relevant for MetaOverlay?
67impl Overlay for MetaOverlay {
68    fn as_any(&self) -> &dyn Any {
69        self
70    }
71    fn capture_base(&self) -> &Option<said::SelfAddressingIdentifier> {
72        &self.capture_base
73    }
74    fn set_capture_base(&mut self, said: &said::SelfAddressingIdentifier) {
75        self.capture_base = Some(said.clone());
76    }
77    fn said(&self) -> &Option<said::SelfAddressingIdentifier> {
78        &self.said
79    }
80    fn overlay_type(&self) -> &OverlayType {
81        &self.overlay_type
82    }
83    fn language(&self) -> Option<&Language> {
84        Some(&self.language)
85    }
86    fn attributes(&self) -> Vec<&String> {
87        vec![]
88    }
89
90    fn add(&mut self, _attribute: &Attribute) {}
91}
92
93impl MetaOverlay {
94    pub fn new(lang: Language, attr_pairs: HashMap<String, String>) -> Self {
95        let overlay_version = "1.1".to_string();
96        Self {
97            capture_base: None,
98            said: None,
99            overlay_type: OverlayType::Meta(overlay_version),
100            language: lang,
101            attr_pairs,
102        }
103    }
104}