pub mod data_validator;
pub use oca_ast_semantics::ast::{
recursive_attributes::NestedAttrTypeFrame, AttributeType, NestedAttrType,
OverlayType, RefValue,
};
pub use oca_bundle_semantics::state::validator::validate as validate_semantics;
pub use oca_bundle_semantics::{
controller::load_oca as load,
state::{
attribute::Attribute,
oca::{overlay, OCABox, OCABundle},
validator::{SemanticValidationStatus, Validator as OCAValidator},
},
};
pub use oca_rs::facade::{
build::{build_from_ocafile, parse_oca_bundle_to_ocafile},
Facade,
};
use oca_rs::{EncodeBundle, HashFunctionCode, SerializationFormats};
use std::collections::HashMap;
use std::sync::{Arc, Mutex, Weak};
pub trait ToJSON {
fn get_json_bundle(&self) -> String;
}
impl ToJSON for OCABundle {
fn get_json_bundle(&self) -> String {
let code = HashFunctionCode::Blake3_256;
let format = SerializationFormats::JSON;
String::from_utf8(self.encode(&code, &format).unwrap()).unwrap()
}
}
lazy_static::lazy_static! {
static ref INFO_CACHE: Mutex<HashMap<usize, Weak<OCABundleInfo>>> = Mutex::new(HashMap::new());
}
pub trait WithInfo {
fn info(&self) -> Arc<OCABundleInfo>;
}
impl WithInfo for OCABundle {
fn info(&self) -> Arc<OCABundleInfo> {
let key = self as *const OCABundle as usize;
let mut cache = INFO_CACHE.lock().unwrap();
if let Some(weak_info) = cache.get(&key) {
if let Some(info) = weak_info.upgrade() {
return info;
}
}
let new_info = Arc::new(OCABundleInfo::new(self));
cache.insert(key, Arc::downgrade(&new_info));
new_info
}
}
pub struct OCABundleInfo {
attributes: HashMap<String, Attribute>,
pub meta: HashMap<String, HashMap<String, String>>,
pub links: Vec<overlay::Link>,
pub framings: Vec<overlay::AttributeFraming>,
}
impl OCABundleInfo {
pub fn new(bundle: &OCABundle) -> Self {
let mut meta = HashMap::new();
let oca_box = OCABox::from(bundle.clone());
if let Some(m) = oca_box.meta {
m.iter().for_each(|(k, v)| {
meta.insert(k.to_639_3().to_string(), v.to_owned());
})
}
let mut overlays = bundle.overlays.clone();
let links: Vec<overlay::Link> = overlays
.iter_mut()
.filter(|o| o.as_any().downcast_ref::<overlay::Link>().is_some())
.map(|o| {
o.as_any()
.downcast_ref::<overlay::Link>()
.unwrap()
.to_owned()
})
.collect();
let framings: Vec<overlay::AttributeFraming> = overlays
.iter_mut()
.filter(|o| {
o.as_any()
.downcast_ref::<overlay::AttributeFraming>()
.is_some()
})
.map(|o| {
o.as_any()
.downcast_ref::<overlay::AttributeFraming>()
.unwrap()
.to_owned()
})
.collect();
Self {
attributes: oca_box.attributes,
meta,
links,
framings,
}
}
pub fn attributes(&self) -> impl Iterator<Item = &Attribute> {
self.attributes.values()
}
pub fn attribute(&self, name: &str) -> Option<&Attribute> {
self.attributes.get(name)
}
}