1use std::io::Read;
2
3use log::info;
4use overlay_file::overlay_registry::OverlayRegistry;
5
6use crate::state::oca_bundle::{OCABundle, OCABundleModel, OCABundleWithRegistry};
7
8pub type GenericError = Box<dyn std::error::Error + Sync + Send>;
9pub type GenericResult<T> = Result<T, GenericError>;
10
11pub fn load_oca(
15 source: &mut dyn Read,
16 overlay_registry: &overlay_file::overlay_registry::OverlayLocalRegistry,
17) -> GenericResult<OCABundleModel> {
18 let mut oca: OCABundle = serde_json::from_reader(source)?;
19
20 for overlay in &mut oca.overlays {
22 let overlay_type = &overlay.model.name;
23 match overlay_registry.get_overlay(overlay_type) {
24 Ok(overlay_def) => {
25 overlay.model.overlay_def = Some(overlay_def.clone());
26 }
27 Err(e) => {
28 return Err(format!(
29 "Failed to find overlay definition for {}: {}",
30 overlay_type, e
31 )
32 .into());
33 }
34 }
35 }
36
37 let bundle_with_registry = OCABundleWithRegistry {
38 bundle: oca,
39 registry: overlay_registry.clone(),
40 };
41 let oca_bundle_model = OCABundleModel::from(bundle_with_registry);
43
44 match validate_bundle(&oca_bundle_model) {
45 Ok(()) => {
46 Ok(oca_bundle_model)
48 }
49 Err(e) => Err(e),
50 }
51}
52
53fn validate_bundle(bundle: &OCABundleModel) -> GenericResult<()> {
56 let said = bundle.digest.clone();
57 let mut mut_bundle = bundle.clone();
58
59 match mut_bundle.compute_and_fill_digest() {
61 Ok(_) => info!("Digest filled successfully"),
62 Err(e) => panic!("Failed to fill digest: {}", e),
63 }
64 if said == mut_bundle.digest {
65 Ok(())
66 } else {
67 Err("Digests do not match".into())
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use overlay_file::overlay_registry::OverlayLocalRegistry;
74
75 use super::load_oca;
76
77 #[test]
78 fn load_oca_bundle_json_from_str() {
79 let data = r#"
80{"v":"OCAS02JSON0009e3_","digest":"EP79WPhSehW5kVwy67UR-bJEoGMUWcN5cK99THUtnBIm","capture_base":{"digest":"EMDyoUr57UN7-Wy3kmF0WyG0xiQieckUdW18VGdEuve9","type":"capture_base/2.0.0","attributes":{"age":"Numeric","car":["refs:EJeWVGxkqxWrdGi0efOzwg1YQK8FrA-ZmtegiVEtAVcu"],"d":"Text","el":"Text","i":"Text","incidentals_spare_parts":[["refs:EJeWVGxkqxWrdGi0efOzwg1YQK8FrA-ZmtegiVEtAVcu"]],"list":["Text"],"name":"Text","passed":"Boolean"}},"overlays":[{"digest":"EEk6wQBfPuqddeVOPFLgSY9qv1ZorGCvip_oQtFdD9GV","capture_base":"EMDyoUr57UN7-Wy3kmF0WyG0xiQieckUdW18VGdEuve9","type":"overlay/meta/2.0.0","language":"en","description":"Entrance credential","name":"Entrance credential"},{"digest":"EPVOc4fR5Nwe2yHzFS-4wBf3kcm7C5D4XNjY9cxnFaQh","capture_base":"EMDyoUr57UN7-Wy3kmF0WyG0xiQieckUdW18VGdEuve9","type":"overlay/character_encoding/2.0.0","attribute_character_encodings":{"d":"utf-8","i":"utf-8","passed":"utf-8"}},{"digest":"EIHoDc5WM8Yxxhvqnc9348DL-OU1FCb9K5eXUuiISztT","capture_base":"EMDyoUr57UN7-Wy3kmF0WyG0xiQieckUdW18VGdEuve9","type":"overlay/conformance/2.0.0","attribute_conformances":{"d":"M","i":"M","passed":"M"}},{"digest":"EEy4mJ4SIxauAyk8FI1QqBa26qG1Fqn2uhN_Vf4RMIbL","capture_base":"EMDyoUr57UN7-Wy3kmF0WyG0xiQieckUdW18VGdEuve9","type":"overlay/label/2.0.0","language":"en","attribute_labels":{"d":"Schema digest","i":"Credential Issuee","passed":"Passed"}},{"digest":"EJi35V6qV5tUhnjDR3qiB2irAKLkbQVu-rU_hehkhop1","capture_base":"EMDyoUr57UN7-Wy3kmF0WyG0xiQieckUdW18VGdEuve9","type":"overlay/format/2.0.0","attribute_formats":{"d":"image/jpeg"}},{"digest":"EPdl6CuC9i9IszrkqvEkv9qZPM-WnX47DOD80dwGiHpL","capture_base":"EMDyoUr57UN7-Wy3kmF0WyG0xiQieckUdW18VGdEuve9","type":"overlay/unit/2.0.0","metric_system":"SI","attribute_units":{"i":"m^2","d":"°"}},{"digest":"EFbS7GQMBi_RCk2Q8cJKR2ohCE--248bH1OQnwiFzmer","capture_base":"EMDyoUr57UN7-Wy3kmF0WyG0xiQieckUdW18VGdEuve9","type":"overlay/cardinality/2.0.0","attribute_cardinalities":{"list":"1-2"}},{"digest":"ED6ktKLPYEmJfYTEo7-YR-xyPwHUgpEOdEwOe_Kr6c22","capture_base":"EMDyoUr57UN7-Wy3kmF0WyG0xiQieckUdW18VGdEuve9","type":"overlay/entry_code/2.0.0","attribute_entry_codes":{"list":"refs:EJeWVGxkqxWrdGi0efOzwg1YQK8FrA-ZmtegiVEtAVcu","el":["o1","o2","o3"]}},{"digest":"EIMaWbfJ98gO1sTucmYdgaZu_u94djMa75BYl8lzkvfc","capture_base":"EMDyoUr57UN7-Wy3kmF0WyG0xiQieckUdW18VGdEuve9","type":"overlay/entry/2.0.0","language":"en","attribute_entries":{"list":"refs:EJeWVGxkqxWrdGi0efOzwg1YQK8FrA-ZmtegiVEtAVcu","el":{"o1":"o1_label","o2":"o2_label","o3":"o3_label"}}}]}
81 "#;
82
83 let registry = OverlayLocalRegistry::from_dir("../overlay-file/core_overlays/").unwrap();
84 let oca_bundle = load_oca(&mut data.as_bytes(), ®istry);
85 println!(">>>> {:?}", oca_bundle);
86 assert!(oca_bundle.is_ok());
87 let oca = oca_bundle.unwrap();
88 assert_eq!(
89 oca.digest.as_ref().map(|d| d.to_string()).as_deref(),
90 Some("EP79WPhSehW5kVwy67UR-bJEoGMUWcN5cK99THUtnBIm")
91 );
92 assert_eq!(oca.capture_base.attributes.len(), 9);
93 }
94}