capability-stripped-string-skeleton 0.1.0

Provides a streamlined representation of a skill tree structure, focusing on a lightweight, stripped-down version that retains essential hierarchical relationships without the full complexity of the original structure.
Documentation
// ---------------- [ File: capability-stripped-string-skeleton/src/from_string_skeleton.rs ]
crate::ix!();

impl From<JustifiedStringSkeleton> for StrippedStringSkeleton {
    fn from(x: JustifiedStringSkeleton) -> Self {
        let skel = StringSkeleton::from(x);
        (&skel).into()
    }
}

/// Below is our updated `From<&StringSkeleton> for StrippedStringSkeleton`
/// implementation. We simply call `promote_missing_child_nodes_with_defaults`
/// at the start, so that none of the aggregator/dispatch children get dropped.
/// After that, the existing logic remains unchanged.
///
/// Make sure to import the `promote_missing_child_nodes_with_defaults` function
/// in whatever module houses this `impl`.
impl From<&StringSkeleton> for StrippedStringSkeleton {
    fn from(x: &StringSkeleton) -> Self {
        use tracing::{trace, debug};

        trace!("Starting conversion from &StringSkeleton to StrippedStringSkeleton");

        // -- NEW STEP: clone the input so we can fix missing aggregator/dispatch children
        let mut temp_skel = x.clone();
        trace!("Promoting any missing aggregator/dispatch children with default LeafHolders...");
        promote_missing_child_nodes_with_defaults(&mut temp_skel);

        debug!("After promoting missing nodes, map size = {}", temp_skel.map().len());

        // Then we proceed as before, but using `temp_skel` instead of `x`.
        let items = temp_skel.map().iter().map(|(_key, node)| {
            match node {
                StringSkeletonNode::Dispatch { name, ordering: _ordering, children } => {
                    debug!("Converting a Dispatch node with name={}", name);
                    let child_vec: Vec<NamedChildSpec> = children.iter().map(|(child_name, cspec)| {
                        NamedChildSpecBuilder::default()
                            .name(child_name.clone())
                            .optional(false)
                            .probability((*cspec.branch_selection_likelihood()).into())
                            .build()
                            .expect("Failed building NamedChildSpec for Dispatch")
                    }).collect();
                    StrippedNodeDataBuilder::default()
                        .name(name.clone())
                        .kind(SkillTreeNodeKind::Dispatch)
                        .n_leaves(None)
                        .capstone(None)
                        .children(Some(child_vec))
                        .build()
                        .expect("Failed building StrippedNodeData for Dispatch")
                }
                StringSkeletonNode::LeafHolder { name, ordering: _ordering, n_leaves, capstone } => {
                    debug!("Converting a LeafHolder node with name={}", name);
                    StrippedNodeDataBuilder::default()
                        .name(name.clone())
                        .kind(SkillTreeNodeKind::LeafHolder)
                        .n_leaves(Some(*n_leaves as usize))
                        .capstone(Some(*capstone))
                        .children(None)
                        .build()
                        .expect("Failed building StrippedNodeData for LeafHolder")
                }
                StringSkeletonNode::Aggregate { name, ordering: _ordering, children } => {
                    debug!("Converting an Aggregate node with name={}", name);
                    let child_vec: Vec<NamedChildSpec> = children.iter().map(|(child_name, cspec)| {
                        NamedChildSpecBuilder::default()
                            .name(child_name.clone())
                            .optional(*cspec.optional())
                            .probability((*cspec.psome_likelihood()).into())
                            .build()
                            .expect("Failed building NamedChildSpec for Aggregate")
                    }).collect();
                    StrippedNodeDataBuilder::default()
                        .name(name.clone())
                        .kind(SkillTreeNodeKind::Aggregate)
                        .n_leaves(None)
                        .capstone(None)
                        .children(Some(child_vec))
                        .build()
                        .expect("Failed building StrippedNodeData for Aggregate")
                }
            }
        }).collect();

        trace!("Completed conversion from &StringSkeleton to StrippedStringSkeleton");

        StrippedStringSkeletonBuilder::default()
            .target_name(x.target_name().to_string())
            .items(items)
            .build()
            .expect("Failed building StrippedStringSkeleton")
    }
}