holochain_types/
zome_types.rs

1//! Helpers for constructing and using zome types correctly.
2pub use error::*;
3use holochain_zome_types::prelude::*;
4use std::collections::HashMap;
5
6#[allow(missing_docs)]
7mod error;
8#[cfg(test)]
9mod test;
10
11/// The number of types of a given type per zome.
12pub type NumZomeTypes = u8;
13/// Zome types at the global scope for a DNA.
14#[derive(Clone, Debug, PartialEq, Default)]
15pub struct GlobalZomeTypes {
16    entries: HashMap<ZomeIndex, NumZomeTypes>,
17    links: HashMap<ZomeIndex, NumZomeTypes>,
18}
19
20impl GlobalZomeTypes {
21    /// Create a new zome types map from the order of
22    /// the iterators. The iterator must be the same order
23    /// as the integrity zomes.
24    ///
25    /// This iterator should contain the number of [`EntryDefIndex`] and [`LinkType`]
26    /// for each integrity zome. If the zome does not have any entries or links,
27    /// then it should still have a zero value set.
28    ///
29    /// # Correct Usage
30    /// You must use an iterator with a deterministic order.
31    ///
32    /// For example [`HashMap`] does not produce
33    /// deterministic iterators so should not be used as the source.
34    #[cfg_attr(feature = "instrument", tracing::instrument(skip_all))]
35    pub fn from_ordered_iterator<I>(ordered_iterator: I) -> ZomeTypesResult<GlobalZomeTypes>
36    where
37        I: IntoIterator<Item = (u8, u8)>,
38    {
39        let r = ordered_iterator.into_iter().enumerate().try_fold(
40            Self::default(),
41            |mut zome_types, (zome_index, (num_entry_types, num_link_types))| {
42                let zome_index: ZomeIndex = u8::try_from(zome_index)
43                    .map_err(|_| ZomeTypesError::ZomeIndexOverflow)?
44                    .into();
45                zome_types.entries.insert(zome_index, num_entry_types);
46                zome_types.links.insert(zome_index, num_link_types);
47                Ok(zome_types)
48            },
49        )?;
50        Ok(r)
51    }
52
53    /// Create a new zome types map within the scope of the given integrity zomes.
54    pub fn in_scope_subset(&self, zomes: &[ZomeIndex]) -> ScopedZomeTypesSet {
55        let entries = zomes.iter().filter_map(|zome_index| {
56            self.entries
57                .get_key_value(zome_index)
58                .map(|(z, l)| (*z, *l))
59        });
60        let entries = new_scope(entries);
61        let links = zomes
62            .iter()
63            .filter_map(|zome_index| self.links.get_key_value(zome_index).map(|(z, l)| (*z, *l)));
64        let links = new_scope(links);
65        ScopedZomeTypesSet { entries, links }
66    }
67}
68
69fn new_scope<T>(iter: impl Iterator<Item = (ZomeIndex, NumZomeTypes)>) -> ScopedZomeTypes<T>
70where
71    T: From<u8>,
72{
73    let iter = iter
74        .map(|(zome_index, len)| (zome_index, (0..len).map(Into::into).collect()))
75        .collect();
76    ScopedZomeTypes(iter)
77}