crate::ix!();
#[derive(AiJsonTemplateWithJustification,AiJsonTemplate,SaveLoad,Debug, Clone, PartialEq, Eq,Serialize, Deserialize, Builder, Default, Getters,MutGetters)]
#[builder(pattern="owned", setter(into))]
#[getset(get="pub",get_mut="pub")]
pub struct StringSkeleton {
#[builder(default = "\"target\".to_string()")]
#[serde(default)]
target_name: String,
map: HashMap<String, StringSkeletonNode>,
}
impl FuzzyFromJsonValue for JustifiedStringSkeleton {
fn fuzzy_from_json_value(value: &Value) -> Result<Self, FuzzyFromJsonValueError> {
trace!("(JustifiedStringSkeleton) Entering fuzzy_from_json_value => {}", value);
let mut top_cloned = value.clone();
flatten_fields_if_present_in_value(&mut top_cloned);
let obj = match top_cloned.as_object() {
Some(o) => {
let keys_collected: Vec<_> = o.keys().cloned().collect();
trace!("(JustifiedStringSkeleton) Top-level keys after flatten => {:?}", keys_collected);
o
}
None => {
error!("(JustifiedStringSkeleton) Not an object => fail");
return Err(FuzzyFromJsonValueError::NotAnObject {
target_type: "JustifiedStringSkeleton",
actual: top_cloned,
});
}
};
let target_name_val = if let Some(raw) = obj.get("target_name") {
raw.to_string().to_kebab_case()
} else {
warn!("(JustifiedGrowerTreeConfiguration) 'depth' missing => default 0");
"target-name-unset".to_string()
};
let target_name_conf = get_f64_field(&obj, "target_name_confidence", "JustifiedGrowerTreeConfiguration").unwrap_or(0.0);
let target_name_just = get_string_field(&obj, "target_name_justification", "JustifiedGrowerTreeConfiguration").unwrap_or_default();
let map_val = obj.get("map").ok_or_else(|| {
error!("(JustifiedStringSkeleton) Missing 'map' => fail");
FuzzyFromJsonValueError::MissingField {
field_name: "map",
target_type: "JustifiedStringSkeleton",
}
})?;
let map_obj = match map_val.as_object() {
Some(m) => {
let map_keys_vec: Vec<_> = m.keys().cloned().collect();
trace!("(JustifiedStringSkeleton) 'map' object => child keys => {:?}", map_keys_vec);
m
}
None => {
error!("(JustifiedStringSkeleton) 'map' must be object => fail");
return Err(FuzzyFromJsonValueError::Other {
target_type: "JustifiedStringSkeleton",
detail: format!("'map' must be an object, got {:?}", map_val),
});
}
};
let mut final_map = HashMap::new();
for (k, v) in map_obj {
if k == "generation_instructions"
|| k == "map_key_template"
|| k == "map_value_template"
|| k == "required" || k == "type" || k == "struct_docs" || k == "variant_docs" {
trace!("(JustifiedStringSkeleton) Skipping meta key='{}' => not a node", k);
continue;
}
trace!("(JustifiedStringSkeleton) Parsing node key='{}' => {}", k, v);
let node_just = match JustifiedStringSkeletonNode::fuzzy_from_json_value(v) {
Ok(nj) => {
trace!("(JustifiedStringSkeleton) Successfully parsed node='{}' => Justified form", k);
nj
}
Err(e) => {
error!("(JustifiedStringSkeleton) Error parsing node='{}' => {:?}", k, e);
return Err(FuzzyFromJsonValueError::Other {
target_type: "JustifiedStringSkeleton",
detail: format!("Error parsing node for key='{}': {:?}", k, e),
});
}
};
final_map.insert(k.clone(), node_just.into());
}
let map_conf = get_f64_field(obj, "map_confidence", "JustifiedStringSkeleton")
.unwrap_or(0.0);
let map_just = get_string_field(obj, "map_justification", "JustifiedStringSkeleton")
.unwrap_or_default();
trace!("(JustifiedStringSkeleton) Successfully built final => map size={}", final_map.len());
Ok(JustifiedStringSkeleton {
target_name: target_name_val,
target_name_confidence: target_name_conf,
target_name_justification: target_name_just,
map: final_map,
map_confidence: map_conf,
map_justification: map_just,
})
}
}