node.rs
  1  #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
  2  pub struct Node {
  3      node: Vec<u8>,
  4      signatures: nonempty::NonEmpty<Vec<u8>>,
  5  }
  6  
  7  #[cfg(test)]
  8  #[test]
  9  fn test_node() {
 10      insta::assert_json_snapshot!(Node {
 11          node: vec![1, 2, 3, 4, 5],
 12          signatures: nonempty::NonEmpty::new(vec![1, 2, 3]),
 13      });
 14  }
 15  
 16  impl Node {
 17      pub fn signatures(&self) -> &nonempty::NonEmpty<Vec<u8>> {
 18          &self.signatures
 19      }
 20  
 21      pub fn from_model_type<S>(
 22          model: &distrox_model::node::Node,
 23          code: multihash_codetable::Code,
 24          signer: &mut S,
 25      ) -> Result<(Self, crate::node_id::NodeId, S::Signature), NodeFromModelTypeError>
 26      where
 27          S: crate::signature::NodeSigner,
 28      {
 29          use multihash_derive::MultihashDigest;
 30  
 31          let deser_node = DeserNode::from(model);
 32          let bytes = serde_json::to_vec(&deser_node).map_err(NodeFromModelTypeError::Transcoding)?;
 33  
 34          let id = distrox_multihash::multihash::Multihash::try_from(code.digest(&bytes))
 35              .map_err(NodeFromModelTypeError::Multihash)?;
 36  
 37          let bytes = NodeNetworkRepresentation(bytes);
 38  
 39          let signature = signer
 40              .sign_node(&bytes)
 41              .map_err(NodeFromModelTypeError::Signer)?;
 42  
 43          Ok((
 44              Node {
 45                  node: bytes.0,
 46                  signatures: nonempty::NonEmpty::singleton(signature.clone().into()),
 47              },
 48              crate::node_id::NodeId::new(id),
 49              signature,
 50          ))
 51      }
 52  
 53      pub fn construct_from_model_type<Sig>(
 54          model: &distrox_model::node::Node,
 55          signatures: nonempty::NonEmpty<Sig>,
 56      ) -> Result<Self, NodeFromModelTypeError>
 57      where
 58          Sig: crate::signature::Signature,
 59      {
 60          let deser_node = DeserNode::from(model);
 61          let bytes = serde_json::to_vec(&deser_node).map_err(NodeFromModelTypeError::Transcoding)?;
 62  
 63          Ok(Node {
 64              node: bytes,
 65              signatures: signatures.map(|s| s.into()),
 66          })
 67      }
 68  
 69      pub fn into_model_repr(self) -> Result<distrox_model::node::Node, NodeIntoModelTypeError> {
 70          serde_json::from_slice(&self.node)
 71              .map(|dnode: DeserNode| {
 72                  distrox_model::node::Node::from_raw_parts(
 73                      dnode.version,
 74                      dnode.parents.into_iter().map(Into::into).collect(),
 75                      dnode.content.map(Into::into),
 76                  )
 77              })
 78              .map_err(NodeIntoModelTypeError)
 79      }
 80  }
 81  
 82  impl crate::network::NetworkType for Node {}
 83  
 84  #[derive(Debug, thiserror::Error)]
 85  pub enum NodeFromModelTypeError {
 86      #[error("Transcoding failed")]
 87      Transcoding(#[source] serde_json::Error),
 88  
 89      #[error("Signing failed")]
 90      Signer(#[source] crate::signature::SigningError),
 91  
 92      #[error("Generating ID failed")]
 93      Multihash(#[source] distrox_multihash::multihash::TryFromMultihashError),
 94  }
 95  
 96  impl crate::model::ModelType for distrox_model::node::Node {}
 97  
 98  #[derive(Debug, thiserror::Error)]
 99  #[error("Failed to deserialize node from JSON represetation")]
100  pub struct NodeIntoModelTypeError(#[source] serde_json::Error);
101  
102  #[derive(derive_more::AsRef)]
103  pub struct NodeNetworkRepresentation(#[as_ref] Vec<u8>);
104  
105  impl TryFrom<&distrox_model::node::Node> for NodeNetworkRepresentation {
106      type Error = NodeFromModelTypeError;
107  
108      fn try_from(value: &distrox_model::node::Node) -> Result<Self, Self::Error> {
109          serde_json::to_vec(&DeserNode::from(value))
110              .map(Self)
111              .map_err(NodeFromModelTypeError::Transcoding)
112      }
113  }
114  
115  impl From<Node> for NodeNetworkRepresentation {
116      fn from(value: Node) -> Self {
117          Self(value.node)
118      }
119  }
120  
121  #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
122  struct DeserNode {
123      version: u64,
124      parents: std::collections::BTreeSet<DeserParentId>,
125      content: Option<DeserContentId>,
126  }
127  
128  impl From<&distrox_model::node::Node> for DeserNode {
129      fn from(value: &distrox_model::node::Node) -> Self {
130          Self {
131              version: value.version(),
132              parents: value
133                  .parent_ids()
134                  .iter()
135                  .copied()
136                  .map(DeserParentId::from)
137                  .collect(),
138              content: value.content().map(DeserContentId::from),
139          }
140      }
141  }
142  
143  #[derive(
144      Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, serde::Serialize, serde::Deserialize,
145  )]
146  #[serde(transparent)]
147  struct DeserParentId(distrox_multihash::multihash::Multihash);
148  
149  impl From<distrox_model::node::NodeId> for DeserParentId {
150      fn from(value: distrox_model::node::NodeId) -> Self {
151          Self(value.inner())
152      }
153  }
154  
155  impl From<DeserParentId> for distrox_model::node::NodeId {
156      fn from(value: DeserParentId) -> Self {
157          distrox_model::node::NodeId::from(value.0)
158      }
159  }
160  
161  #[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
162  #[serde(transparent)]
163  struct DeserContentId(distrox_multihash::multihash::Multihash);
164  
165  impl From<distrox_model::content::ContentId> for DeserContentId {
166      fn from(value: distrox_model::content::ContentId) -> Self {
167          Self(value.inner())
168      }
169  }
170  
171  impl From<DeserContentId> for distrox_model::content::ContentId {
172      fn from(value: DeserContentId) -> Self {
173          distrox_model::content::ContentId::from(value.0)
174      }
175  }