cranpose-core 0.0.60

Core runtime for a Jetpack Compose inspired UI framework in Rust
Documentation
use super::super::{DetachedSubtree, GroupKey, GroupRecord, PayloadAnchor, PayloadRecord};
use super::{
    anchors,
    groups::{validate_slot_tree, SlotTreeChecks, SlotTreeView},
    SlotInvariantError, SlotTreeContext,
};
use crate::collections::map::HashSet;

struct DetachedSlotTreeChecks {
    root_key: GroupKey,
    payload_anchors: HashSet<PayloadAnchor>,
}

impl DetachedSlotTreeChecks {
    fn new(root_key: GroupKey) -> Self {
        Self {
            root_key,
            payload_anchors: HashSet::default(),
        }
    }
}

impl SlotTreeChecks for DetachedSlotTreeChecks {
    fn validate_payload(
        &mut self,
        _group_index: usize,
        _group: &GroupRecord,
        _payload_index: usize,
        payload: &PayloadRecord,
    ) -> Result<(), SlotInvariantError> {
        if self.payload_anchors.insert(payload.anchor) {
            return Ok(());
        }
        Err(SlotInvariantError::DuplicatePayloadAnchor {
            tree: SlotTreeContext::Detached {
                root_key: self.root_key,
            },
            payload_anchor: payload.anchor,
        })
    }
}

impl DetachedSubtree {
    pub(crate) fn validate_detached(&self) -> Result<(), SlotInvariantError> {
        let Some(root) = self.groups.first() else {
            return Err(SlotInvariantError::DetachedSubtreeEmpty);
        };
        let root_key = root.key;

        anchors::validate_detached_anchor_set(root_key, &self.groups)?;

        let mut checks = DetachedSlotTreeChecks::new(root_key);
        validate_slot_tree(
            SlotTreeView {
                tree: SlotTreeContext::Detached { root_key },
                groups: &self.groups,
                payloads: &self.payloads,
                nodes: &self.nodes,
            },
            &mut checks,
        )
    }
}