use super::model::{AasCollection, AasSemId, AasSubmodel, AasSubmodelElement};
use super::property::{boolean_property, double_property, integer_property, string_property};
pub fn map_dpp_to_aas_submodel(submodel_id: &str, dpp_data: &serde_json::Value) -> AasSubmodel {
let elements = match dpp_data {
serde_json::Value::Object(map) => map
.iter()
.map(|(key, val)| json_value_to_element(key, val))
.collect(),
_ => vec![],
};
AasSubmodel {
id: submodel_id.into(),
id_short: "DigitalProductPassport".into(),
model_type: "Submodel".into(),
kind: "Instance".into(),
semantic_id: Some(AasSemId::external(
super::semantic_ids::DIGITAL_PRODUCT_PASSPORT,
)),
submodel_elements: elements,
}
}
pub(crate) fn json_value_to_element(key: &str, value: &serde_json::Value) -> AasSubmodelElement {
match value {
serde_json::Value::String(s) => string_property(key, s, None, None),
serde_json::Value::Number(n) => {
if let Some(i) = n.as_i64() {
integer_property(key, i, None, None)
} else if let Some(f) = n.as_f64() {
double_property(key, f, None, None)
} else {
string_property(key, &n.to_string(), None, None)
}
}
serde_json::Value::Bool(b) => boolean_property(key, *b, None, None),
serde_json::Value::Object(map) => {
let children: Vec<AasSubmodelElement> = map
.iter()
.map(|(k, v)| json_value_to_element(k, v))
.collect();
AasSubmodelElement::SubmodelElementCollection(AasCollection {
id_short: key.into(),
value: children,
semantic_id: None,
})
}
serde_json::Value::Array(arr) => {
let children: Vec<AasSubmodelElement> = arr
.iter()
.enumerate()
.map(|(i, v)| json_value_to_element(&format!("item_{i}"), v))
.collect();
AasSubmodelElement::SubmodelElementCollection(AasCollection {
id_short: key.into(),
value: children,
semantic_id: None,
})
}
serde_json::Value::Null => string_property(key, "", None, None),
}
}