From 7ae0325d7e54df8db88bc7bc757c3cb674a0fb0f Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 8 Dec 2021 17:50:29 +0100 Subject: Split codebase in subcrates for lib, cli and gui Signed-off-by: Matthias Beyer --- lib/src/types/node.rs | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 lib/src/types/node.rs (limited to 'lib/src/types/node.rs') diff --git a/lib/src/types/node.rs b/lib/src/types/node.rs new file mode 100644 index 0000000..eb5679b --- /dev/null +++ b/lib/src/types/node.rs @@ -0,0 +1,88 @@ +use anyhow::Result; + +use std::convert::TryFrom; + +#[derive(Debug, Eq, PartialEq, getset::Getters)] +pub struct Node { + /// Version + #[getset(get = "pub")] + version: String, + + /// Parent Nodes, identified by cid + parents: Vec, + + /// The actual payload of the node, which is stored in another document identified by this cid + payload: ipfs::Cid, +} + +impl Into for Node { + fn into(self) -> ipfs::Ipld { + let mut map = std::collections::BTreeMap::new(); + map.insert(String::from("version"), ipfs::Ipld::String(self.version)); + map.insert(String::from("parents"), ipfs::Ipld::List(self.parents.into_iter().map(ipfs::Ipld::Link).collect())); + map.insert(String::from("payload"), ipfs::Ipld::Link(self.payload)); + ipfs::Ipld::Map(map) + } +} + +impl TryFrom for Node { + type Error = anyhow::Error; + + fn try_from(ipld: ipfs::Ipld) -> Result { + let missing_field = |name: &'static str| move || anyhow::anyhow!("Missing field {}", name); + let field_wrong_type = |name: &str, expty: &str| anyhow::bail!("Field {} has wrong type, expected {}", name, expty); + match ipld { + ipfs::Ipld::Map(map) => { + let version = match map.get("version").ok_or_else(missing_field("version"))? { + ipfs::Ipld::String(s) => s.to_string(), + _ => return field_wrong_type("version", "String") + }; + + let parents = match map.get("parents").ok_or_else(missing_field("parents"))? { + ipfs::Ipld::List(s) => { + s.into_iter() + .map(|parent| -> Result { + match parent { + ipfs::Ipld::Link(cid) => Ok(cid.clone()), + _ => anyhow::bail!("Field in parents has wrong type, expected Link"), + } + }) + .collect::>>()? + }, + _ => return field_wrong_type("parents", "Vec") + }; + + let payload = match map.get("payload").ok_or_else(missing_field("payload"))? { + ipfs::Ipld::Link(cid) => cid.clone(), + _ => return field_wrong_type("payload", "Link") + }; + + Ok(Node { + version, + parents, + payload + }) + } + + _ => anyhow::bail!("Unexpected type, expected map") + } + } +} + +impl Node { + pub fn new(version: String, parents: Vec, payload: ipfs::Cid) -> Self { + Self { + version, + parents, + payload, + } + } + + pub fn parents(&self) -> Vec { + self.parents.clone() + } + + pub fn payload(&self) -> ipfs::Cid { + self.payload.clone() + } +} -- cgit v1.2.3