Skip to main content

oca_sdk_rs/
lib.rs

1//! # OCA SDK
2//!
3//! Compact yet powerful SDK for working with OCA bundles.
4//!
5//! # Features
6//!
7//! - Create OCA Bundle from OCAFile.
8//! - Validate OCA Bundle semantics.
9//! - Validate data against OCA Bundle.
10//! - Traverse through OCA Bundle attributes.
11
12// --- Standard library imports ---
13use std::collections::HashMap;
14use std::sync::{Arc, Mutex, Weak};
15mod data_validator;
16
17// -- Re-exports all modules in consistant interface
18pub mod oca {
19    pub mod utils {
20        pub mod said {
21            pub use oca_bundle::state::oca_bundle::error;
22            pub use oca_bundle::state::oca_bundle::HashFunction;
23            pub use oca_bundle::state::oca_bundle::HashFunctionCode;
24            pub use oca_bundle::state::oca_bundle::SelfAddressingIdentifier;
25        }
26    }
27    pub mod bundle {
28        pub use oca_bundle::build::from_ast;
29        pub use oca_bundle::controller::load_oca as load;
30        pub use oca_bundle::state::attribute::Attribute;
31        pub use oca_bundle::state::validator::{
32            SemanticValidationStatus, Validator as OCAValidator,
33        };
34        pub use oca_bundle::state::{
35            oca_bundle::{OCABundle, OCABundleModel},
36            validator::validate as validate_semantics,
37        };
38    }
39    pub mod file {
40        pub use oca_file::ocafile::*;
41    }
42    pub mod overlay_file {
43        pub use oca_ast::ast::{
44            recursive_attributes::NestedAttrTypeFrame, AttributeType, NestedAttrType, RefValue,
45        };
46        pub use overlay_file::overlay_registry::OverlayLocalRegistry;
47    }
48    pub mod validator {
49        pub use crate::data_validator::*;
50    }
51}
52
53pub trait ToJSON {
54    fn get_json_bundle(&self) -> String;
55}
56
57impl ToJSON for oca::bundle::OCABundleModel {
58    fn get_json_bundle(&self) -> String {
59        let oca_bundle = oca::bundle::OCABundle::from(self.clone());
60        let result = serde_json::to_string_pretty(&oca_bundle);
61        match result {
62            Ok(json) => json,
63            Err(e) => format!("Error converting to JSON: {}", e),
64        }
65    }
66}
67
68lazy_static::lazy_static! {
69    static ref INFO_CACHE: Mutex<HashMap<usize, Weak<OCABundleInfo>>> = Mutex::new(HashMap::new());
70}
71
72pub trait WithInfo {
73    fn info(&self) -> Arc<OCABundleInfo>;
74}
75
76impl WithInfo for oca::bundle::OCABundleModel {
77    fn info(&self) -> Arc<OCABundleInfo> {
78        let key = self as *const oca::bundle::OCABundleModel as usize;
79        let mut cache = INFO_CACHE.lock().unwrap();
80        if let Some(weak_info) = cache.get(&key) {
81            if let Some(info) = weak_info.upgrade() {
82                return info;
83            }
84        }
85
86        let new_info = Arc::new(OCABundleInfo::new(self));
87        cache.insert(key, Arc::downgrade(&new_info));
88        new_info
89    }
90}
91
92pub struct OCABundleInfo {
93    // TODO Find out if this should be option or not
94    attributes: Option<HashMap<String, oca::bundle::Attribute>>,
95    pub meta: HashMap<String, HashMap<String, String>>,
96}
97
98impl OCABundleInfo {
99    pub fn new(bundle: &oca::bundle::OCABundleModel) -> Self {
100        let meta = HashMap::new();
101        // TODO fix it
102        // let oca_box = OCABox::from(bundle.clone());
103        // if let Some(m) = oca_box.meta {
104        //     m.iter().for_each(|(k, v)| {
105        //         meta.insert(k.unwrap().to_639_3().to_string(), v.to_owned());
106        //     })
107        // }
108
109        Self {
110            attributes: bundle.attributes.clone(),
111            meta,
112        }
113    }
114
115    pub fn attributes(&self) -> impl Iterator<Item = &oca::bundle::Attribute> {
116        self.attributes.as_ref().unwrap().values()
117    }
118
119    pub fn attribute(&self, name: &str) -> Option<&oca::bundle::Attribute> {
120        self.attributes.as_ref().unwrap().get(name)
121    }
122}