holochain_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::WireDelete;
9use crate::action::WireNewEntryAction;
10use crate::action::WireUpdateRelationship;
11use crate::dht_op::DhtOpResult;
12use crate::dht_op::RenderedOp;
13use crate::dht_op::RenderedOps;
14use holo_hash::*;
15use holochain_zome_types::op::ChainOpType;
16use holochain_zome_types::prelude::*;
17
18/// Convenience function for when you have a RecordEntry but need
19/// a Option EntryHashed
20pub fn option_entry_hashed(entry: RecordEntry) -> Option<EntryHashed> {
21    match entry {
22        RecordEntry::Present(e) => Some(EntryHashed::from_content_sync(e)),
23        _ => None,
24    }
25}
26
27/// Condensed data needed for a get entry request.
28// TODO: Could use actual compression to get even smaller.
29#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SerializedBytes, Default)]
30pub struct WireEntryOps {
31    /// Any actions that created this entry.
32    pub creates: Vec<Judged<WireNewEntryAction>>,
33    /// Any deletes that deleted this entry.
34    // TODO: Can remove the entry hash from [`WireDelete`]
35    // to save more data.
36    pub deletes: Vec<Judged<WireDelete>>,
37    /// Any updates on this entry.
38    pub updates: Vec<Judged<WireUpdateRelationship>>,
39    /// The entry data shared across all actions.
40    pub entry: Option<EntryData>,
41}
42
43/// All entry data common to an get entry request.
44#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SerializedBytes)]
45pub struct EntryData {
46    /// The entry shared across all actions.
47    pub entry: Entry,
48    /// The entry_type shared across all actions.
49    pub entry_type: EntryType,
50}
51
52impl WireEntryOps {
53    /// Create an empty wire response.
54    pub fn new() -> Self {
55        Self::default()
56    }
57    /// Render these ops to their full types.
58    pub fn render(self) -> DhtOpResult<RenderedOps> {
59        let Self {
60            creates,
61            deletes,
62            updates,
63            entry,
64        } = self;
65        match entry {
66            Some(EntryData { entry, entry_type }) => {
67                let mut ops = Vec::with_capacity(creates.len() + deletes.len() + updates.len());
68                let entry_hashed = EntryHashed::from_content_sync(entry);
69                for op in creates {
70                    let status = op.validation_status();
71                    let (action, signature) = op
72                        .data
73                        .into_signed_action(entry_type.clone(), entry_hashed.as_hash().clone())
74                        .into();
75
76                    ops.push(RenderedOp::new(
77                        action,
78                        signature,
79                        status,
80                        ChainOpType::StoreEntry,
81                    )?);
82                }
83                for op in deletes {
84                    let status = op.validation_status();
85                    let op = op.data;
86                    let signature = op.signature;
87                    let action = Action::Delete(op.delete);
88
89                    ops.push(RenderedOp::new(
90                        action,
91                        signature,
92                        status,
93                        ChainOpType::RegisterDeletedEntryAction,
94                    )?);
95                }
96                for op in updates {
97                    let status = op.validation_status();
98                    let (action, signature) = op
99                        .data
100                        .into_signed_action(entry_hashed.as_hash().clone())
101                        .into();
102
103                    ops.push(RenderedOp::new(
104                        action,
105                        signature,
106                        status,
107                        ChainOpType::RegisterUpdatedContent,
108                    )?);
109                }
110                Ok(RenderedOps {
111                    entry: Some(entry_hashed),
112                    ops,
113                    warrant: None,
114                })
115            }
116            None => Ok(Default::default()),
117        }
118    }
119}