oca_rs/facade/
bundle.rs

1use std::io::Read;
2
3use oca_bundle_semantics::state::oca::OCABundle as StructuralBundle;
4use said::derivation::HashFunctionCode;
5use said::version::SerializationInfo;
6use said::{sad::SerializationFormats, sad::SAD};
7use serde::{Deserialize, Serialize};
8
9pub type GenericError = Box<dyn std::error::Error + Sync + Send>;
10
11pub fn load_oca(source: &mut dyn Read) -> Result<Bundle, GenericError> {
12    let oca: Bundle = serde_json::from_reader(source)?;
13    Ok(oca)
14}
15
16#[derive(Debug)]
17pub enum BundleElement {
18    Structural(StructuralBundle),
19    Transformation(transformation_file::state::Transformation),
20}
21
22#[derive(SAD, Serialize, Debug, Deserialize, Clone)]
23#[version(protocol = "B", major = 1, minor = 0)]
24pub struct Bundle {
25    #[said]
26    #[serde(rename = "d")]
27    pub said: Option<said::SelfAddressingIdentifier>,
28    #[serde(rename = "m")]
29    pub structural: Option<StructuralBundle>,
30    #[serde(rename = "t")]
31    pub transformations: Vec<transformation_file::state::Transformation>,
32}
33
34impl Bundle {
35    pub fn new() -> Self {
36        Self {
37            said: None,
38            structural: None,
39            transformations: vec![],
40        }
41    }
42
43    pub fn add(&mut self, element: BundleElement) {
44        match element {
45            BundleElement::Structural(structural) => self.add_structural(structural),
46            BundleElement::Transformation(transformation) => {
47                self.add_transformation(transformation)
48            }
49        }
50    }
51
52    fn add_structural(&mut self, structural: StructuralBundle) {
53        self.structural = Some(structural);
54    }
55
56    fn add_transformation(&mut self, transformation: transformation_file::state::Transformation) {
57        self.transformations.push(transformation);
58    }
59
60    pub fn fill_said(&mut self) {
61        let code = HashFunctionCode::Blake3_256;
62        let format = SerializationFormats::JSON;
63        self.compute_digest(&code, &format);
64    }
65
66    pub fn encode(&self) -> Result<String, serde_json::Error> {
67        let code = HashFunctionCode::Blake3_256;
68        let format = SerializationFormats::JSON;
69
70        let structural = self.structural.as_ref().unwrap();
71        let structural_str = String::from_utf8(structural.encode(&code, &format).unwrap()).unwrap();
72
73        let mut transformations_str = String::new();
74        let mut transformations_iter = self.transformations.iter().peekable();
75        while let Some(transformation) = transformations_iter.next() {
76            let s = String::from_utf8(transformation.encode(&code, &format).unwrap()).unwrap();
77            let transformation_str = match transformations_iter.peek() {
78                Some(_) => format!("{},", s),
79                None => s,
80            };
81            transformations_str.push_str(&transformation_str);
82        }
83
84        let result = format!(
85            r#"{{"d":"","m":{},"t":[{}]}}"#,
86            structural_str, transformations_str
87        );
88
89        let protocol_version = said::ProtocolVersion::new("OCAB", 0, 0).unwrap();
90        let versioned_result = said::make_me_sad(&result, code, protocol_version).unwrap();
91
92        Ok(versioned_result)
93    }
94}
95
96impl Default for Bundle {
97    fn default() -> Self {
98        Self::new()
99    }
100}