1use crate::data_storage::Namespace;
2use oca_ast_semantics::ast::{BundleContent, CaptureContent, Content, ObjectKind, RefValue};
3use oca_bundle_semantics::state::oca::OCABundle;
4use serde::{ser::SerializeStruct, Serialize};
5use std::collections::HashSet;
6
7use super::Facade;
8
9impl Facade {
10 pub fn explore(&self, said: String) -> Option<Relationship> {
11 let relations_u8_res = self.db.get(Namespace::OCARelations, &said);
12
13 match relations_u8_res {
14 Ok(Some(relations_u8)) => {
15 let relationship: Relationship = relations_u8.into();
16 Some(Relationship {
17 base_object: OCAObject::new(self, said),
18 relations: relationship.relations,
19 })
20 }
21 _ => None,
22 }
23 }
24
25 fn insert_oca_objects_metadata(&mut self, oca_bundle: OCABundle) -> Result<(), String> {
26 self.db.insert(
27 Namespace::OCARelations,
28 &format!("{}.metadata", oca_bundle.said.clone().unwrap()),
29 &[ObjectKind::OCABundle(BundleContent {
30 said: oca_ast_semantics::ast::ReferenceAttrType::Reference(RefValue::Name(
31 "".to_string(),
32 )),
33 })
34 .into()],
35 )?;
36 self.db.insert(
37 Namespace::OCARelations,
38 &format!("{}.metadata", oca_bundle.capture_base.said.clone().unwrap()),
39 &[ObjectKind::CaptureBase(CaptureContent {
40 attributes: None,
41 properties: None,
42 flagged_attributes: None,
43 })
44 .into()],
45 )?;
46 oca_bundle.overlays.iter().for_each(|overlay| {
47 let _ = self.db.insert(
48 Namespace::OCARelations,
49 &format!("{}.metadata", overlay.said().clone().unwrap()),
50 &[ObjectKind::Overlay(
51 overlay.overlay_type().clone(),
52 Content {
53 attributes: None,
54 properties: None,
55 },
56 )
57 .into()],
58 );
59 });
60
61 Ok(())
62 }
63
64 pub fn add_relations(&mut self, oca_bundle: OCABundle) -> Result<(), String> {
65 self.insert_oca_objects_metadata(oca_bundle.clone())?;
66
67 let oca_bundle_said = oca_bundle.said.clone().unwrap().to_string();
68 let capture_base_said = oca_bundle.capture_base.said.clone().unwrap().to_string();
69
70 let mut oca_bundle_rel =
71 self.explore(oca_bundle_said.clone())
72 .unwrap_or(Relationship::new(OCAObject::new(
73 self,
74 oca_bundle_said.clone(),
75 )));
76 oca_bundle_rel.add_relation(OCAObject::new(self, capture_base_said.clone()));
77
78 let mut capture_base_rel =
79 self.explore(capture_base_said.clone())
80 .unwrap_or(Relationship::new(OCAObject::new(
81 self,
82 capture_base_said.clone(),
83 )));
84 capture_base_rel.add_relation(OCAObject::new(self, oca_bundle_said.clone()));
85
86 for overlay in oca_bundle.overlays {
87 let overlay_said = overlay.said().clone().unwrap().to_string();
88
89 oca_bundle_rel.add_relation(OCAObject::new(self, overlay_said.clone()));
90 capture_base_rel.add_relation(OCAObject::new(self, overlay_said.clone()));
91
92 let mut overlay_rel = self
93 .explore(overlay_said.clone())
94 .unwrap_or(Relationship::new(OCAObject::new(
95 self,
96 overlay_said.clone(),
97 )));
98
99 overlay_rel.add_relation(OCAObject::new(self, oca_bundle_said.clone()));
100 overlay_rel.add_relation(OCAObject::new(self, capture_base_said.clone()));
101 let overlay_rel_u8: Vec<u8> = overlay_rel.clone().into();
102 self.db.insert(
103 Namespace::OCARelations,
104 &overlay_said.clone(),
105 &overlay_rel_u8,
106 )?;
107 }
108
109 let oca_bundle_rel_u8: Vec<u8> = oca_bundle_rel.clone().into();
110 self.db.insert(
111 Namespace::OCARelations,
112 &oca_bundle_rel.base_object.said,
113 &oca_bundle_rel_u8,
114 )?;
115
116 let capture_base_rel_u8: Vec<u8> = capture_base_rel.clone().into();
117 self.db.insert(
118 Namespace::OCARelations,
119 &capture_base_rel.base_object.said,
120 &capture_base_rel_u8,
121 )?;
122
123 Ok(())
124 }
125
126 fn object_type(&self, said: String) -> ObjectKind {
127 let object_type = self
128 .db
129 .get(Namespace::OCARelations, &format!("{}.metadata", said))
130 .unwrap();
131
132 (*object_type.unwrap().first().unwrap()).into()
133 }
134}
135
136#[derive(Clone)]
137pub struct Relationship {
138 pub base_object: OCAObject,
139 pub relations: HashSet<OCAObject>,
140}
141
142impl Relationship {
143 fn new(base_object: OCAObject) -> Self {
144 Self {
145 base_object,
146 relations: HashSet::new(),
147 }
148 }
149
150 fn add_relation(&mut self, object: OCAObject) {
151 self.relations.insert(object);
152 }
153}
154
155impl From<Relationship> for Vec<u8> {
156 fn from(val: Relationship) -> Self {
157 let mut result: Vec<u8> = Vec::new();
158
159 val.relations.iter().for_each(|object| {
160 result.push(object.object_type.clone().into());
161 result.push(object.said.len().try_into().unwrap());
162 result.extend(object.said.as_bytes());
163 });
164
165 result
166 }
167}
168
169impl From<Vec<u8>> for Relationship {
170 fn from(val: Vec<u8>) -> Self {
171 let mut result = Relationship::new(OCAObject {
172 said: "".to_string(),
173 object_type: ObjectKind::OCABundle(BundleContent {
174 said: oca_ast_semantics::ast::ReferenceAttrType::Reference(RefValue::Name(
175 "".to_string(),
176 )),
177 }),
178 });
179
180 let mut tmp_val = val.clone();
181 while !tmp_val.is_empty() {
182 let said_len = tmp_val[1];
183 let (o_u8, split_val) = tmp_val.split_at(2 + said_len as usize);
184 result.add_relation(OCAObject::from(o_u8.to_vec()));
185 tmp_val = split_val.to_vec();
186 }
187
188 result
189 }
190}
191
192impl From<Vec<u8>> for OCAObject {
193 fn from(val: Vec<u8>) -> Self {
194 let object_type = val[0];
195 let said_len = val[1];
196 let said = String::from_utf8(val[2..2 + said_len as usize].to_vec()).unwrap();
197 Self {
198 said,
199 object_type: object_type.into(),
200 }
201 }
202}
203
204#[derive(Eq, PartialEq, Hash, Clone, Debug)]
205pub struct OCAObject {
206 pub said: String,
207 pub object_type: ObjectKind,
208}
209
210impl Serialize for OCAObject {
211 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
212 where
213 S: serde::Serializer,
214 {
215 #[derive(Serialize)]
216 struct OverlayMetadata {
217 kind: ObjectKind,
218 }
219
220 let mut state = serializer.serialize_struct("OCAObject", 3)?;
221 state.serialize_field("said", &self.said)?;
222 match &self.object_type {
223 ObjectKind::OCABundle(_) | ObjectKind::CaptureBase(_) => {
224 state.serialize_field("object_type", &self.object_type)?
225 }
226 ObjectKind::Overlay(_, _) => {
227 state.serialize_field("object_type", "Overlay")?;
228 let overlay_metadata = OverlayMetadata {
229 kind: self.object_type.clone(),
230 };
231 state.serialize_field("metadata", &overlay_metadata)?
232 }
233 }
234 state.end()
235 }
236}
237
238impl OCAObject {
239 fn new(facade: &Facade, said: String) -> Self {
240 Self {
241 said: said.clone(),
242 object_type: facade.object_type(said),
243 }
244 }
245}