capability_skeleton_string/
aggregate_child_spec.rs

1// ---------------- [ File: capability-skeleton-string/src/aggregate_child_spec.rs ]
2crate::ix!();
3
4/// Use this object to specify per-child optionality and toggle probability for a model branch within an `Aggregate` node.
5///
6#[derive(Eq,Default,AiJsonTemplateWithJustification,Builder,SaveLoad,Getters,Debug, Copy,Clone, PartialEq, Serialize, Deserialize, AiJsonTemplate)]
7#[builder(pattern="owned", setter(into))]
8#[getset(get = "pub")]
9pub struct AggregateChildSpec {
10
11    /// Set the `psome_likelihood` field to indicate the probability this child (if `optional`) is *something* as opposed to *nothing*.
12    ///
13    /// This field has no meaning if `optional` is *false.
14    ///
15    /// Values may be 0..100 inclusive. Values over this maximum will be clipped.
16    ///
17    #[serde(default)]
18    #[serde(deserialize_with = "fuzzy_u8")]
19    psome_likelihood: u8,
20
21    /// Set the `optional` field to indicate whether or not this tree branch is *optional*.
22    #[serde(default)]
23    optional: bool,
24}
25
26impl FuzzyFromJsonValue for JustifiedAggregateChildSpec {
27    fn fuzzy_from_json_value(value: &serde_json::Value)
28        -> Result<Self, FuzzyFromJsonValueError>
29    {
30        trace!("(JustifiedAggregateChildSpec) Entering fuzzy_from_json_value => {}", value);
31
32        // must be an object
33        let obj = match value.as_object() {
34            Some(m) => {
35                trace!("(JustifiedAggregateChildSpec) Found object => proceed to parse fields");
36                m
37            }
38            None => {
39                error!("(JustifiedAggregateChildSpec) Not an object => fail");
40                return Err(FuzzyFromJsonValueError::NotAnObject {
41                    target_type: "JustifiedAggregateChildSpec",
42                    actual: value.clone(),
43                });
44            }
45        };
46
47        // parse psome_likelihood as u8
48        let psome_val = obj.get("psome_likelihood").ok_or_else(|| {
49            error!("(JustifiedAggregateChildSpec) Missing 'psome_likelihood' => fail");
50            FuzzyFromJsonValueError::MissingField {
51                field_name: "psome_likelihood",
52                target_type: "JustifiedAggregateChildSpec",
53            }
54        })?;
55        let psome_likelihood = fuzzy_u8(psome_val).map_err(|e| {
56            error!("(JustifiedAggregateChildSpec) Could not parse psome_likelihood => {:?}", e);
57            FuzzyFromJsonValueError::Other {
58                target_type: "JustifiedAggregateChildSpec",
59                detail: e.to_string(),
60            }
61        })?;
62
63        // parse optional as bool
64        let optional_val = obj.get("optional").ok_or_else(|| {
65            error!("(JustifiedAggregateChildSpec) Missing 'optional' => fail");
66            FuzzyFromJsonValueError::MissingField {
67                field_name: "optional",
68                target_type: "JustifiedAggregateChildSpec",
69            }
70        })?;
71        let optional_bool = match optional_val {
72            serde_json::Value::Bool(b) => *b,
73            other => {
74                error!("(JustifiedAggregateChildSpec) 'optional' must be bool => got {:?}", other);
75                return Err(FuzzyFromJsonValueError::Other {
76                    target_type: "JustifiedAggregateChildSpec",
77                    detail: format!("Expected 'optional' to be bool, got {:?}", other),
78                });
79            }
80        };
81
82        // parse the confidence & justification if present
83        let psome_likelihood_confidence = obj.get("psome_likelihood_confidence")
84            .and_then(|val| val.as_f64())
85            .unwrap_or(0.0);
86        let psome_likelihood_justification = obj.get("psome_likelihood_justification")
87            .and_then(|val| val.as_str())
88            .unwrap_or("no justification provided")
89            .to_string();
90
91        let optional_confidence = obj.get("optional_confidence")
92            .and_then(|val| val.as_f64())
93            .unwrap_or(0.0);
94        let optional_justification = obj.get("optional_justification")
95            .and_then(|val| val.as_str())
96            .unwrap_or("no justification provided")
97            .to_string();
98
99        trace!("(JustifiedAggregateChildSpec) Successfully parsed => psome_likelihood={}, optional={}", 
100            psome_likelihood, optional_bool);
101
102        Ok(JustifiedAggregateChildSpec {
103            psome_likelihood,
104            psome_likelihood_confidence,
105            psome_likelihood_justification,
106            optional: optional_bool,
107            optional_confidence,
108            optional_justification,
109        })
110    }
111}