Skip to main content

phoxal_model/component/
mod.rs

1//! Canonical component facts used after authored documents are loaded.
2//!
3//! Runtime consumers use these unversioned values through [`crate::Robot`].
4
5pub mod capability;
6
7use std::collections::BTreeMap;
8
9use crate::identity::CapabilityId;
10use crate::simulation::Simulation;
11use crate::structure::Structure;
12use capability::Capability;
13
14/// One component *type*: the capabilities and structure every instance of it
15/// has, and how a simulated world models it.
16///
17/// The simulation lives on the type rather than in a parallel map keyed the same
18/// way, because it is only ever meaningful together with the capabilities it
19/// models: a simulated capability that names none of them is the one error the
20/// pairing makes impossible to write.
21#[derive(phoxal_macros::DescribeWire, serde::Serialize, serde::Deserialize, Debug, Clone)]
22#[serde(deny_unknown_fields)]
23pub struct Component {
24    capabilities: BTreeMap<CapabilityId, Capability>,
25    structure: Structure,
26    simulation: Option<Simulation>,
27}
28
29impl Component {
30    pub(crate) fn new(
31        capabilities: BTreeMap<CapabilityId, Capability>,
32        structure: Structure,
33        simulation: Option<Simulation>,
34    ) -> Self {
35        Self {
36            capabilities,
37            structure,
38            simulation,
39        }
40    }
41
42    /// How a simulated world models this type, when a document authored one.
43    #[must_use]
44    pub const fn simulation(&self) -> Option<&Simulation> {
45        self.simulation.as_ref()
46    }
47
48    /// The named capability, if this type declares it.
49    #[must_use]
50    pub fn capability(&self, capability_id: &str) -> Option<&Capability> {
51        self.capabilities.get(capability_id)
52    }
53
54    /// Every declared capability, ordered by capability id.
55    pub fn capabilities(&self) -> impl ExactSizeIterator<Item = (&CapabilityId, &Capability)> {
56        self.capabilities.iter()
57    }
58
59    /// The component's own structure, in component-local identities.
60    #[must_use]
61    pub fn structure(&self) -> &Structure {
62        &self.structure
63    }
64}