holochain_integrity_types/
info.rs

1//! Information about the current zome and dna.
2use crate::action::ZomeIndex;
3use crate::zome::ZomeName;
4use crate::DnaModifiers;
5use crate::EntryDefIndex;
6use crate::EntryDefs;
7use crate::FunctionName;
8use crate::LinkType;
9use holo_hash::DnaHash;
10use holochain_serialized_bytes::prelude::*;
11
12#[cfg(test)]
13mod test;
14
15/// The properties of the current dna/zome being called.
16#[allow(missing_docs)]
17#[derive(Clone, Debug, Serialize, Deserialize, SerializedBytes, PartialEq)]
18pub struct ZomeInfo {
19    pub name: ZomeName,
20    /// The position of this zome in the `dna.json`
21    pub id: ZomeIndex,
22    pub properties: SerializedBytes,
23    pub entry_defs: EntryDefs,
24    // @todo make this include function signatures when they exist.
25    pub extern_fns: Vec<FunctionName>,
26    /// All the zome types that are in scope for this zome.
27    pub zome_types: ScopedZomeTypesSet,
28}
29
30impl ZomeInfo {
31    /// Create a new ZomeInfo.
32    pub fn new(
33        name: ZomeName,
34        id: ZomeIndex,
35        properties: SerializedBytes,
36        entry_defs: EntryDefs,
37        extern_fns: Vec<FunctionName>,
38        zome_types: ScopedZomeTypesSet,
39    ) -> Self {
40        Self {
41            name,
42            id,
43            properties,
44            entry_defs,
45            extern_fns,
46            zome_types,
47        }
48    }
49}
50
51/// Placeholder for a real network seed type. See [`DnaModifiers`].
52pub type NetworkSeed = String;
53
54#[derive(Debug, Serialize, Deserialize)]
55/// Information about the current DNA.
56pub struct DnaInfoV1 {
57    /// The name of this DNA.
58    pub name: String,
59    /// The hash of this DNA.
60    pub hash: DnaHash,
61    /// The properties of this DNA.
62    pub properties: SerializedBytes,
63    // In ZomeIndex order as to match corresponding `ZomeInfo` for each.
64    /// The zomes in this DNA.
65    pub zome_names: Vec<ZomeName>,
66}
67
68#[derive(Debug, Serialize, Deserialize)]
69/// Information about the current DNA.
70pub struct DnaInfoV2 {
71    /// The name of this DNA.
72    pub name: String,
73    /// The hash of this DNA.
74    pub hash: DnaHash,
75    /// The modifiers for this DNA.
76    pub modifiers: DnaModifiers,
77    // In ZomeIndex order as to match corresponding `ZomeInfo` for each.
78    /// The zomes in this DNA.
79    pub zome_names: Vec<ZomeName>,
80}
81
82/// Convenience alias to the latest `DnaInfoN`.
83pub type DnaInfo = DnaInfoV2;
84
85#[derive(Clone, Debug, Serialize, Deserialize, SerializedBytes, PartialEq, Default)]
86/// The set of [`EntryDefIndex`] and [`LinkType`]s in scope for the calling zome.
87pub struct ScopedZomeTypesSet {
88    /// All the entry [`EntryDefIndex`]s in scope for this zome.
89    pub entries: ScopedZomeTypes<EntryDefIndex>,
90    /// All the entry [`LinkType`]s in scope for this zome.
91    pub links: ScopedZomeTypes<LinkType>,
92}
93
94#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
95/// zome types that are in scope for the calling zome.
96pub struct ScopedZomeTypes<T>(pub Vec<(ZomeIndex, Vec<T>)>);
97
98impl<T> Default for ScopedZomeTypes<T> {
99    fn default() -> Self {
100        Self(Default::default())
101    }
102}
103
104#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
105/// A key to the [`ScopedZomeTypes`] container.
106pub struct ZomeTypesKey<T>
107where
108    T: U8Index + Copy,
109{
110    /// The index into the [`ZomeIndex`] vec.
111    pub zome_index: ZomeDependencyIndex,
112    /// The index into the types vec.
113    pub type_index: T,
114}
115
116/// A key to the [`ScopedZomeTypes<EntryDefIndex>`] container.
117pub type ZomeEntryTypesKey = ZomeTypesKey<EntryDefIndex>;
118/// A key to the [`ScopedZomeTypes<LinkType>`] container.
119pub type ZomeLinkTypesKey = ZomeTypesKey<LinkType>;
120
121#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
122/// The index into the [`ZomeIndex`] vec.
123pub struct ZomeDependencyIndex(pub u8);
124
125#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
126/// A type with the zome that it is defined in.
127pub struct ScopedZomeType<T> {
128    /// The zome that defines this type.
129    pub zome_index: ZomeIndex,
130    /// The type that is defined.
131    pub zome_type: T,
132}
133
134/// An [`EntryDefIndex`] within the scope of the zome where it's defined.
135pub type ScopedEntryDefIndex = ScopedZomeType<EntryDefIndex>;
136/// A [`LinkType`] within the scope of the zome where it's defined.
137pub type ScopedLinkType = ScopedZomeType<LinkType>;
138
139impl<T> ScopedZomeTypes<T>
140where
141    T: U8Index + Copy,
142{
143    /// Get a [`ScopedZomeType`] if one exist at this key.
144    pub fn get<K>(&self, key: K) -> Option<ScopedZomeType<T>>
145    where
146        K: Into<ZomeTypesKey<T>>,
147    {
148        let key = key.into();
149        self.0
150            .get(key.zome_index.index())
151            .and_then(|(zome_index, types)| {
152                types
153                    .get(key.type_index.index())
154                    .copied()
155                    .map(|zome_type| ScopedZomeType {
156                        zome_index: *zome_index,
157                        zome_type,
158                    })
159            })
160    }
161
162    /// Find the user type in the given iterator that matches this [`ScopedZomeType`].
163    pub fn find<I, K>(&self, iter: I, scoped_type: ScopedZomeType<T>) -> Option<I::Item>
164    where
165        I: IntoIterator<Item = K>,
166        K: Into<ZomeTypesKey<T>> + Copy,
167        T: PartialEq,
168    {
169        iter.into_iter()
170            .find_map(|key| (self.get(key)? == scoped_type).then_some(key))
171    }
172
173    /// Find the [`ZomeTypesKey`] for this [`ScopedZomeType`].
174    pub fn find_key(&self, scoped_type: ScopedZomeType<T>) -> Option<ZomeTypesKey<T>>
175    where
176        T: PartialEq,
177        T: From<u8>,
178    {
179        self.0
180            .iter()
181            .position(|(zome_index, _)| *zome_index == scoped_type.zome_index)
182            .and_then(|zome_index| {
183                // Safe to index because we just checked position.
184                self.0[zome_index]
185                    .1
186                    .iter()
187                    .position(|zome_type| *zome_type == scoped_type.zome_type)
188                    .and_then(|type_index| {
189                        Some(ZomeTypesKey {
190                            zome_index: u8::try_from(zome_index).ok()?.into(),
191                            type_index: u8::try_from(type_index).ok()?.into(),
192                        })
193                    })
194            })
195    }
196
197    /// Get all the [`ZomeIndex`] dependencies for the calling zome.
198    pub fn dependencies(&self) -> impl Iterator<Item = ZomeIndex> + '_ {
199        self.0.iter().map(|(zome_index, _)| *zome_index)
200    }
201}
202
203impl From<EntryDefIndex> for ZomeEntryTypesKey {
204    fn from(type_index: EntryDefIndex) -> Self {
205        Self {
206            zome_index: 0.into(),
207            type_index,
208        }
209    }
210}
211
212impl From<LinkType> for ZomeLinkTypesKey {
213    fn from(type_index: LinkType) -> Self {
214        Self {
215            zome_index: 0.into(),
216            type_index,
217        }
218    }
219}
220
221#[doc(hidden)]
222/// This is an internally used trait for checking
223/// enum lengths at compile time.
224/// This is used by proc macros in the
225/// `hdk_derive` crate and should not be used directly.
226pub trait EnumLen {
227    /// The total length of an enum (possibly recusively)
228    /// known at compile time.
229    const ENUM_LEN: u8;
230}
231
232#[doc(hidden)]
233/// This is an internally used trait for checking
234/// enum variant lengths at compile time.
235/// This is used by proc macros in the
236/// `hdk_derive` crate and should not be used directly.
237/// `V` is the variant index.
238pub trait EnumVariantLen<const V: u8> {
239    /// The starting point of this enum variant.
240    const ENUM_VARIANT_START: u8;
241    /// The length of this enum variant.
242    /// This could include the recusive length of a nested enum.
243    const ENUM_VARIANT_INNER_LEN: u8;
244    /// The ending point of this variant.
245    const ENUM_VARIANT_LEN: u8 = Self::ENUM_VARIANT_START + Self::ENUM_VARIANT_INNER_LEN;
246}
247
248/// Helper trait for types that are internally
249/// represented as [`u8`] but need to be used
250/// as indicies into containers.
251pub trait U8Index {
252    /// Get the [`usize`] index from this type.
253    fn index(&self) -> usize;
254}
255
256impl U8Index for ZomeDependencyIndex {
257    fn index(&self) -> usize {
258        self.0 as usize
259    }
260}
261impl U8Index for EntryDefIndex {
262    fn index(&self) -> usize {
263        self.0 as usize
264    }
265}
266impl U8Index for LinkType {
267    fn index(&self) -> usize {
268        self.0 as usize
269    }
270}
271
272impl From<u8> for ZomeDependencyIndex {
273    fn from(v: u8) -> Self {
274        Self(v)
275    }
276}
277
278impl From<()> for ZomeEntryTypesKey {
279    fn from(_: ()) -> Self {
280        unimplemented!("Should not ever be used")
281    }
282}