oca_bundle_semantics/state/oca/overlay/
entry.rs

1use crate::state::{attribute::Attribute, entries::EntriesElement, 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 Entries {
11    fn set_entry(&mut self, l: Language, entry: EntriesElement);
12}
13
14impl Entries for Attribute {
15    fn set_entry(&mut self, l: Language, entry: EntriesElement) {
16        if let Some(entries) = &mut self.entries {
17            entries.insert(l, entry);
18        } else {
19            let mut entries = HashMap::new();
20            entries.insert(l, entry);
21            self.entries = Some(entries);
22        }
23    }
24}
25
26pub fn serialize_attributes<S>(
27    attributes: &HashMap<String, EntriesElement>,
28    s: S,
29) -> Result<S::Ok, S::Error>
30where
31    S: Serializer,
32{
33    use std::collections::BTreeMap;
34
35    let mut ser = s.serialize_map(Some(attributes.len()))?;
36    let sorted_attributes: BTreeMap<_, _> = attributes.iter().collect();
37    for (k, v) in sorted_attributes {
38        ser.serialize_entry(k, v)?;
39    }
40    ser.end()
41}
42
43#[derive(SAD, Serialize, Deserialize, Debug, Clone)]
44pub struct EntryOverlay {
45    #[said]
46    #[serde(rename = "d")]
47    said: Option<said::SelfAddressingIdentifier>,
48    capture_base: Option<said::SelfAddressingIdentifier>,
49    #[serde(rename = "type")]
50    overlay_type: OverlayType,
51    language: Language,
52    #[serde(serialize_with = "serialize_attributes")]
53    pub attribute_entries: HashMap<String, EntriesElement>,
54}
55
56impl Overlay for EntryOverlay {
57    fn as_any(&self) -> &dyn Any {
58        self
59    }
60    fn capture_base(&self) -> &Option<said::SelfAddressingIdentifier> {
61        &self.capture_base
62    }
63    fn set_capture_base(&mut self, said: &said::SelfAddressingIdentifier) {
64        self.capture_base = Some(said.clone());
65    }
66    fn said(&self) -> &Option<said::SelfAddressingIdentifier> {
67        &self.said
68    }
69    fn overlay_type(&self) -> &OverlayType {
70        &self.overlay_type
71    }
72    fn language(&self) -> Option<&Language> {
73        Some(&self.language)
74    }
75    fn attributes(&self) -> Vec<&String> {
76        self.attribute_entries.keys().collect::<Vec<&String>>()
77    }
78
79    fn add(&mut self, attribute: &Attribute) {
80        if let Some(entries) = &attribute.entries {
81            if let Some(tr) = entries.get(&self.language) {
82                self.attribute_entries
83                    .insert(attribute.name.clone(), tr.clone());
84            }
85        }
86    }
87}
88impl EntryOverlay {
89    pub fn new(lang: Language) -> Self {
90        let overlay_version = "1.1".to_string();
91        Self {
92            capture_base: None,
93            said: None,
94            overlay_type: OverlayType::Entry(overlay_version),
95            language: lang,
96            attribute_entries: HashMap::new(),
97        }
98    }
99}