crate::ix!();
impl FuzzyFromJsonValue for CoreStringSkeleton {
fn fuzzy_from_json_value(value: &serde_json::Value) -> Result<Self, FuzzyFromJsonValueError> {
let mut obj = match value.as_object() {
Some(m) => m.clone(),
None => {
return Err(FuzzyFromJsonValueError::NotAnObject {
target_type: "CoreStringSkeleton",
actual: value.clone(),
});
}
};
flatten_fields_if_present(&mut obj);
let bytes = match serde_json::to_vec(&serde_json::Value::Object(obj)) {
Ok(b) => b,
Err(e) => {
return Err(FuzzyFromJsonValueError::Other {
target_type: "CoreStringSkeleton",
detail: format!("Could not convert object to bytes: {e}"),
});
}
};
let mut track = serde_path_to_error::Track::new();
let mut d = serde_json::Deserializer::from_slice(&bytes);
let mut path_d = serde_path_to_error::Deserializer::new(&mut d, &mut track);
match Deserialize::deserialize(path_d) {
Ok(core) => Ok(core),
Err(path_err) => {
warn!(
"Fuzzy parse for CoreStringSkeleton failed: {:?}",
path_err
);
Err(FuzzyFromJsonValueError::SerdeError {
target_type: "CoreStringSkeleton",
source: path_err,
})
}
}
}
}
#[tracing::instrument(level = "trace", skip_all)]
fn flatten_fields_if_present(obj: &mut serde_json::Map<String, serde_json::Value>) {
if let Some(fields_val) = obj.remove("fields") {
if let serde_json::Value::Object(fields_map) = fields_val {
trace!("Detected 'fields' object => flattening into top-level.");
for (k, v) in fields_map {
if obj.contains_key(&k) {
warn!("While flattening 'fields', key '{}' already exists in top-level => skipping overwrite.", k);
continue;
}
obj.insert(k, v);
}
} else {
debug!("Key 'fields' is present but not an object => putting it back into top-level as 'fields'.");
obj.insert("fields".to_string(), fields_val);
}
} else {
trace!("No 'fields' key found => nothing to flatten.");
}
}