oca_bundle_semantics/state/oca/overlay/
meta.rs1use 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
66impl 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}