holochain_zome_types/
entry.rs

1//! An Entry is a unit of data in a Holochain Source Chain.
2//!
3//! This module contains all the necessary definitions for Entry, which broadly speaking
4//! refers to any data which will be written into the ContentAddressableStorage, or the EntityAttributeValueStorage.
5//! It defines serialization behaviour for entries. Here you can find the complete list of
6//! entry_types, and special entries, like deletion_entry and cap_entry.
7
8use crate::action::ChainTopOrdering;
9use holochain_integrity_types::EntryDefIndex;
10use holochain_integrity_types::EntryType;
11use holochain_integrity_types::EntryVisibility;
12use holochain_integrity_types::ScopedEntryDefIndex;
13use holochain_integrity_types::ZomeIndex;
14use holochain_serialized_bytes::prelude::*;
15
16mod app_entry_bytes;
17pub use app_entry_bytes::*;
18
19pub use holochain_integrity_types::entry::*;
20
21#[derive(
22    Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
23)]
24/// Either an [`EntryDefIndex`] or one of:
25/// - [EntryType::CapGrant]
26/// - [EntryType::CapClaim]
27///
28/// Which don't have an index.
29pub enum EntryDefLocation {
30    /// App defined entries always have a unique [`u8`] index
31    /// within the Dna.
32    App(AppEntryDefLocation),
33    /// [`CapClaim`](holochain_integrity_types::EntryDefId::CapClaim) is committed to and
34    /// validated by all integrity zomes in the dna.
35    CapClaim,
36    /// [`CapGrant`](holochain_integrity_types::EntryDefId::CapGrant) is committed to and
37    /// validated by all integrity zomes in the dna.
38    CapGrant,
39}
40
41#[derive(
42    Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
43)]
44/// The location of an app entry definition.
45pub struct AppEntryDefLocation {
46    /// The zome that defines this entry type.
47    pub zome_index: ZomeIndex,
48    /// The entry type within the zome.
49    pub entry_def_index: EntryDefIndex,
50}
51
52#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
53/// Options for controlling how get is executed.
54pub struct GetOptions {
55    /// Configure whether data should be fetched from the network or only from the local
56    /// databases.
57    pub strategy: GetStrategy,
58}
59
60impl GetOptions {
61    /// Fetch latest metadata from the network,
62    /// and otherwise fall back to locally cached metadata.
63    ///
64    /// If the current agent is an authority for this hash, this call will not
65    /// go to the network.
66    pub fn network() -> Self {
67        Self {
68            strategy: GetStrategy::Network,
69        }
70    }
71    /// Gets the action/entry and its metadata from local databases only.
72    /// No network call is made.
73    pub fn local() -> Self {
74        Self {
75            strategy: GetStrategy::Local,
76        }
77    }
78}
79
80impl Default for GetOptions {
81    fn default() -> Self {
82        Self::network()
83    }
84}
85
86#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)]
87/// Set if data should be fetched from the network or only from the local
88/// databases.
89pub enum GetStrategy {
90    /// Fetch latest metadata from the network,
91    /// and otherwise fall back to locally cached metadata.
92    ///
93    /// If the current agent is an authority for this hash, this call will not
94    /// go to the network.
95    Network,
96    /// Gets the action/entry and its metadata from local databases only.
97    /// No network call is made.
98    Local,
99}
100
101/// Zome input to create an entry.
102#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, SerializedBytes)]
103pub struct CreateInput {
104    /// The global type index for this entry (if it has one).
105    pub entry_location: EntryDefLocation,
106    /// The visibility of this entry.
107    pub entry_visibility: EntryVisibility,
108    /// Entry body.
109    pub entry: crate::entry::Entry,
110    /// ChainTopBehaviour for the write.
111    pub chain_top_ordering: ChainTopOrdering,
112}
113
114impl CreateInput {
115    /// Constructor.
116    pub fn new(
117        entry_location: impl Into<EntryDefLocation>,
118        entry_visibility: EntryVisibility,
119        entry: crate::entry::Entry,
120        chain_top_ordering: ChainTopOrdering,
121    ) -> Self {
122        Self {
123            entry_location: entry_location.into(),
124            entry_visibility,
125            entry,
126            chain_top_ordering,
127        }
128    }
129
130    /// Consume into an Entry.
131    pub fn into_entry(self) -> Entry {
132        self.entry
133    }
134
135    /// Accessor.
136    pub fn chain_top_ordering(&self) -> &ChainTopOrdering {
137        &self.chain_top_ordering
138    }
139}
140
141impl AsRef<crate::Entry> for CreateInput {
142    fn as_ref(&self) -> &crate::Entry {
143        &self.entry
144    }
145}
146
147/// Zome input for get and get_details calls.
148#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
149pub struct GetInput {
150    /// Any DHT hash to pass to get or get_details.
151    pub any_dht_hash: holo_hash::AnyDhtHash,
152    /// Options for the call.
153    pub get_options: crate::entry::GetOptions,
154}
155
156impl GetInput {
157    /// Constructor.
158    pub fn new(any_dht_hash: holo_hash::AnyDhtHash, get_options: crate::entry::GetOptions) -> Self {
159        Self {
160            any_dht_hash,
161            get_options,
162        }
163    }
164}
165
166/// Zome input type for all update operations.
167#[derive(PartialEq, Debug, Deserialize, Serialize, Clone)]
168pub struct UpdateInput {
169    /// Action of the record being updated.
170    pub original_action_address: holo_hash::ActionHash,
171    /// Entry body.
172    pub entry: crate::entry::Entry,
173    /// ChainTopBehaviour for the write.
174    pub chain_top_ordering: ChainTopOrdering,
175}
176
177/// Zome input for all delete operations.
178#[derive(PartialEq, Debug, Deserialize, Serialize, Clone)]
179pub struct DeleteInput {
180    /// Action of the record being deleted.
181    pub deletes_action_hash: holo_hash::ActionHash,
182    /// Chain top ordering behaviour for the delete.
183    pub chain_top_ordering: ChainTopOrdering,
184}
185
186impl DeleteInput {
187    /// Constructor.
188    pub fn new(
189        deletes_action_hash: holo_hash::ActionHash,
190        chain_top_ordering: ChainTopOrdering,
191    ) -> Self {
192        Self {
193            deletes_action_hash,
194            chain_top_ordering,
195        }
196    }
197}
198
199impl From<holo_hash::ActionHash> for DeleteInput {
200    /// Sets [`ChainTopOrdering`] to `default` = `Strict` when created from a hash.
201    fn from(deletes_action_hash: holo_hash::ActionHash) -> Self {
202        Self {
203            deletes_action_hash,
204            chain_top_ordering: ChainTopOrdering::default(),
205        }
206    }
207}
208
209impl EntryDefLocation {
210    /// Create an [`EntryDefLocation::App`].
211    pub fn app(
212        zome_index: impl Into<ZomeIndex>,
213        entry_def_index: impl Into<EntryDefIndex>,
214    ) -> Self {
215        Self::App(AppEntryDefLocation {
216            zome_index: zome_index.into(),
217            entry_def_index: entry_def_index.into(),
218        })
219    }
220}
221
222impl From<ScopedEntryDefIndex> for AppEntryDefLocation {
223    fn from(s: ScopedEntryDefIndex) -> Self {
224        Self {
225            zome_index: s.zome_index,
226            entry_def_index: s.zome_type,
227        }
228    }
229}
230
231impl From<ScopedEntryDefIndex> for EntryDefLocation {
232    fn from(s: ScopedEntryDefIndex) -> Self {
233        Self::App(s.into())
234    }
235}
236
237/// Check the entry variant matches the variant in the actions entry type
238pub fn entry_type_matches(entry_type: &EntryType, entry: &Entry) -> bool {
239    #[allow(clippy::match_like_matches_macro)]
240    match (entry_type, entry) {
241        (EntryType::AgentPubKey, Entry::Agent(_)) => true,
242        (EntryType::App(_), Entry::App(_)) => true,
243        (EntryType::App(_), Entry::CounterSign(_, _)) => true,
244        (EntryType::CapClaim, Entry::CapClaim(_)) => true,
245        (EntryType::CapGrant, Entry::CapGrant(_)) => true,
246        _ => false,
247    }
248}