holochain_integrity_types/
dna_modifiers.rs

1//! # DNA Properties Support types
2
3use crate::prelude::*;
4use holochain_serialized_bytes::prelude::*;
5
6/// Modifiers of this DNA - the network seed, properties and origin time - as
7/// opposed to the actual DNA code. These modifiers are included in the DNA
8/// hash computation.
9#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
10#[cfg_attr(feature = "full-dna-def", derive(derive_builder::Builder))]
11pub struct DnaModifiers {
12    /// The network seed of a DNA is included in the computation of the DNA hash.
13    /// The DNA hash in turn determines the network peers and the DHT, meaning
14    /// that only peers with the same DNA hash of a shared DNA participate in the
15    /// same network and co-create the DHT. To create a separate DHT for the DNA,
16    /// a unique network seed can be specified.
17    // TODO: consider Vec<u8> instead (https://github.com/holochain/holochain/pull/86#discussion_r412689085)
18    pub network_seed: NetworkSeed,
19
20    /// Any arbitrary application properties can be included in this object.
21    #[cfg_attr(feature = "full-dna-def", builder(default = "().try_into().unwrap()"))]
22    pub properties: SerializedBytes,
23}
24
25impl DnaModifiers {
26    /// Replace fields in the modifiers with any Some fields in the argument.
27    /// None fields remain unchanged.
28    pub fn update(mut self, modifiers: DnaModifiersOpt) -> DnaModifiers {
29        self.network_seed = modifiers.network_seed.unwrap_or(self.network_seed);
30        self.properties = modifiers.properties.unwrap_or(self.properties);
31        self
32    }
33}
34
35/// [`DnaModifiers`] options of which all are optional.
36#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
37pub struct DnaModifiersOpt<P = SerializedBytes> {
38    /// see [`DnaModifiers`]
39    pub network_seed: Option<NetworkSeed>,
40    /// see [`DnaModifiers`]
41    pub properties: Option<P>,
42}
43
44impl<P: TryInto<SerializedBytes, Error = E>, E: Into<SerializedBytesError>> Default
45    for DnaModifiersOpt<P>
46{
47    fn default() -> Self {
48        Self::none()
49    }
50}
51
52impl<P: TryInto<SerializedBytes, Error = E>, E: Into<SerializedBytesError>> DnaModifiersOpt<P> {
53    /// Constructor with all fields set to `None`
54    pub fn none() -> Self {
55        Self {
56            network_seed: None,
57            properties: None,
58        }
59    }
60
61    /// Serialize the properties field into SerializedBytes
62    pub fn serialized(self) -> Result<DnaModifiersOpt<SerializedBytes>, E> {
63        let Self {
64            network_seed,
65            properties,
66        } = self;
67        let properties = if let Some(p) = properties {
68            Some(p.try_into()?)
69        } else {
70            None
71        };
72        Ok(DnaModifiersOpt {
73            network_seed,
74            properties,
75        })
76    }
77
78    /// Return a modified form with the `network_seed` field set
79    pub fn with_network_seed(mut self, network_seed: NetworkSeed) -> Self {
80        self.network_seed = Some(network_seed);
81        self
82    }
83
84    /// Return a modified form with the `properties` field set
85    pub fn with_properties(mut self, properties: P) -> Self {
86        self.properties = Some(properties);
87        self
88    }
89
90    /// Check if at least one of the options is set.
91    pub fn has_some_option_set(&self) -> bool {
92        self.network_seed.is_some() || self.properties.is_some()
93    }
94}
95
96/// Trait to convert from dna properties into specified type
97pub trait TryFromDnaProperties {
98    /// The error associated with this conversion.
99    type Error;
100
101    /// Attempts to deserialize DNA properties into specified type
102    fn try_from_dna_properties() -> Result<Self, Self::Error>
103    where
104        Self: Sized;
105}