diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-11-27 12:33:06 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-11-27 12:33:06 +0100 |
commit | 00c8048c463485285b11c6e0e42d21483157834c (patch) | |
tree | 76d54f49168c24d4d6b177e08043810d612095ad /src | |
parent | d2fbb50aba8d88aa6a18e36e46905356cfeb30b9 (diff) |
Implement putting a block on the chain
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'src')
-rw-r--r-- | src/cid.rs | 7 | ||||
-rw-r--r-- | src/client.rs | 69 | ||||
-rw-r--r-- | src/consts.rs | 2 | ||||
-rw-r--r-- | src/types/node.rs | 5 | ||||
-rw-r--r-- | src/types/payload.rs | 5 |
5 files changed, 87 insertions, 1 deletions
@@ -29,6 +29,13 @@ impl TryToCid for ipfs_api_backend_hyper::response::AddResponse { } } +impl TryToCid for ipfs_api_backend_hyper::response::DagPutResponse { + fn try_to_cid(self) -> Result<Cid> { + log::debug!("Transforming to CID => {:?}", self); + string_to_cid(self.cid.cid_string) + } +} + impl daglib::NodeId for Cid { } diff --git a/src/client.rs b/src/client.rs index 0225488..a000407 100644 --- a/src/client.rs +++ b/src/client.rs @@ -9,6 +9,9 @@ use crate::cid::Cid; use crate::cid::TryToCid; use crate::config::Config; use crate::ipfs_client::IpfsClient; +use crate::types::Node; +use crate::types::Payload; +use crate::types::DateTime; pub struct Client { ipfs: IpfsClient, @@ -38,6 +41,54 @@ impl Client { .map_err(anyhow::Error::from) .and_then(crate::ipfs_client::backend::response::AddResponse::try_to_cid) } + + /// Post a text block + /// + /// Pass in the parents if there are any. + /// + /// # Note + /// + /// Does not verify if the `parents` cids point to actual Nodes! + /// + /// # Returns + /// + /// Returns the Cid of the newly created block, or an error + pub async fn post_text_block(&self, parents: Vec<Cid>, text: String) -> Result<Cid> { + self.post_text_block_with_datetime(parents, text, now()).await + } + + // For testing + async fn post_text_block_with_datetime(&self, parents: Vec<Cid>, text: String, datetime: DateTime) -> Result<Cid> { + let text_blob_cid = self.post_text_blob(text).await?; + + let payload = Payload::new(mime::TEXT_PLAIN_UTF_8.as_ref().to_string(), datetime, text_blob_cid); + let payload_cid = self.post_payload(payload).await?; + + let node = Node::new(crate::consts::protocol_version(), parents, payload_cid); + self.post_node(node).await + } + + async fn post_payload(&self, payload: Payload) -> Result<Cid> { + self.post_serializable(&payload).await + } + + async fn post_node(&self, node: Node) -> Result<Cid> { + self.post_serializable(&node).await + } + + async fn post_serializable<S: serde::Serialize>(&self, s: &S) -> Result<Cid> { + let payload_s = serde_json::to_string(s)?; + let payload_c = Cursor::new(payload_s); + self.ipfs + .dag_put(payload_c) + .await + .map_err(anyhow::Error::from) + .and_then(crate::ipfs_client::backend::response::DagPutResponse::try_to_cid) + } +} + +fn now() -> DateTime { + chrono::offset::Utc::now().into() } #[cfg(test)] @@ -59,4 +110,22 @@ mod tests { assert_eq!(cid.unwrap().as_ref(), "QmY2T5EfgLn8qWCt8eus6VX1gJuAp1nmUSdmoehgMxznAf"); } + #[tokio::test] + async fn test_post_text_block() { + use chrono::TimeZone; + + let _ = env_logger::try_init(); + let ipfs = IpfsClient::from_str("http://localhost:5001").unwrap(); + let config = Config::default(); + let client = Client::new(ipfs, config); + + let datetime = chrono::prelude::Utc.ymd(2021, 11, 27) + .and_hms(12, 30, 0) + .into(); + + let cid = client.post_text_block_with_datetime(Vec::new(), String::from("text"), datetime).await; + assert!(cid.is_ok()); + assert_eq!(cid.unwrap().as_ref(), "bafyreifqa7jqsazxvl53jb6sflzbk4nkv4j7b5jos6hlzh4fq55bjbvk3m"); + } + } diff --git a/src/consts.rs b/src/consts.rs index e5c880c..79ff2f5 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -1,4 +1,4 @@ -pub fn v1() -> String { +pub fn protocol_version() -> String { String::from("1") } diff --git a/src/types/node.rs b/src/types/node.rs index 1fce691..60b10d1 100644 --- a/src/types/node.rs +++ b/src/types/node.rs @@ -18,3 +18,8 @@ impl daglib::Node for Node { } } +impl Node { + pub fn new(v: String, parents: Vec<crate::cid::Cid>, payload: crate::cid::Cid) -> Self { + Self { v, parents, payload } + } +} diff --git a/src/types/payload.rs b/src/types/payload.rs index 6f74deb..5b6cfb1 100644 --- a/src/types/payload.rs +++ b/src/types/payload.rs @@ -10,3 +10,8 @@ pub struct Payload { content: crate::cid::Cid, } +impl Payload { + pub fn new(mime: String, timestamp: DateTime, content: crate::cid::Cid) -> Self { + Self { mime, timestamp, content } + } +} |