summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml1
-rw-r--r--src/cid.rs1
-rw-r--r--src/client.rs71
-rw-r--r--src/types/datetime.rs2
-rw-r--r--src/types/node.rs12
-rw-r--r--src/types/payload.rs6
6 files changed, 86 insertions, 7 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 7da53ef..ddfc31c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -41,3 +41,4 @@ ed25519-dalek = "*"
http = "0.2"
serde = "1"
serde_json = "1"
+getset = "0.1"
diff --git a/src/cid.rs b/src/cid.rs
index fe2d0f3..e89ef75 100644
--- a/src/cid.rs
+++ b/src/cid.rs
@@ -11,7 +11,6 @@ use anyhow::Result;
#[serde(transparent)]
pub struct Cid(String);
-#[cfg(test)]
impl AsRef<str> for Cid {
fn as_ref(&self) -> &str {
self.0.as_ref()
diff --git a/src/client.rs b/src/client.rs
index f984dfa..5523666 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -3,6 +3,7 @@ use std::io::Cursor;
use anyhow::Result;
use futures::FutureExt;
use futures::TryFutureExt;
+use futures::TryStreamExt;
use ipfs_api_backend_hyper::IpfsApi;
use crate::cid::Cid;
@@ -85,6 +86,35 @@ impl Client {
.map_err(anyhow::Error::from)
.and_then(crate::ipfs_client::backend::response::DagPutResponse::try_to_cid)
}
+
+ pub async fn get_node(&self, cid: Cid) -> Result<Node> {
+ self.get_deserializeable::<Node>(cid).await
+ }
+
+ pub async fn get_payload(&self, cid: Cid) -> Result<Payload> {
+ self.get_deserializeable::<Payload>(cid).await
+ }
+
+ async fn get_deserializeable<D: serde::de::DeserializeOwned>(&self, cid: Cid) -> Result<D> {
+ let bytes = self.ipfs
+ .dag_get(cid.as_ref())
+ .map_ok(|chunk| chunk.to_vec())
+ .try_concat()
+ .await?;
+
+ let s = String::from_utf8(bytes)?;
+ serde_json::from_str(&s).map_err(anyhow::Error::from)
+ }
+
+ pub async fn get_content_text(&self, cid: Cid) -> Result<String> {
+ let bytes = self.ipfs
+ .cat(cid.as_ref())
+ .map_ok(|chunk| chunk.to_vec())
+ .try_concat()
+ .await?;
+
+ String::from_utf8(bytes).map_err(anyhow::Error::from)
+ }
}
fn now() -> DateTime {
@@ -128,4 +158,45 @@ mod tests {
assert_eq!(cid.unwrap().as_ref(), "bafyreifqa7jqsazxvl53jb6sflzbk4nkv4j7b5jos6hlzh4fq55bjbvk3m");
}
+ #[tokio::test]
+ async fn test_post_text_node_roundtrip() {
+ 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: crate::types::DateTime = chrono::prelude::Utc.ymd(2021, 11, 27)
+ .and_hms(12, 30, 0)
+ .into();
+
+ let text = "text-roundtrip";
+
+ let cid = client.post_text_node_with_datetime(Vec::new(), String::from(text), datetime.clone()).await;
+ assert!(cid.is_ok());
+ let cid = cid.unwrap();
+ assert_eq!(cid.as_ref(), "bafyreibenqhh2fqf33mdvm4b4k7kpymnyhuduebwdmaxraxttld7i2bbbi");
+
+ let node = client.get_node(cid).await;
+ assert!(node.is_ok());
+ let node = node.unwrap();
+
+ assert_eq!(*node.version(), crate::consts::protocol_version());
+ assert!(node.parents().is_empty());
+
+ let payload = client.get_payload(node.payload().clone()).await;
+ assert!(payload.is_ok());
+ let payload = payload.unwrap();
+
+ assert_eq!(payload.mime(), mime::TEXT_PLAIN_UTF_8.as_ref());
+ assert_eq!(payload.timestamp(), &datetime);
+
+ let content = client.get_content_text(payload.content().clone()).await;
+ assert!(content.is_ok());
+ let content = content.unwrap();
+
+ assert_eq!(content, text);
+ }
+
}
diff --git a/src/types/datetime.rs b/src/types/datetime.rs
index 9034c26..6735731 100644
--- a/src/types/datetime.rs
+++ b/src/types/datetime.rs
@@ -1,6 +1,6 @@
use anyhow::Error;
-#[derive(Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
+#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
pub struct DateTime(chrono::DateTime<chrono::Utc>);
diff --git a/src/types/node.rs b/src/types/node.rs
index 60b10d1..278fa7f 100644
--- a/src/types/node.rs
+++ b/src/types/node.rs
@@ -1,12 +1,16 @@
-#[derive(Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
+#[derive(Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, getset::Getters)]
pub struct Node {
/// Version
- v: String,
+ #[serde(rename = "v")]
+ #[getset(get = "pub")]
+ version: String,
/// Parent Nodes, identified by cid
+ #[getset(get = "pub")]
parents: Vec<crate::cid::Cid>,
/// The actual payload of the node, which is stored in another document identified by this cid
+ #[getset(get = "pub")]
payload: crate::cid::Cid,
}
@@ -19,7 +23,7 @@ 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 }
+ pub fn new(version: String, parents: Vec<crate::cid::Cid>, payload: crate::cid::Cid) -> Self {
+ Self { version, parents, payload }
}
}
diff --git a/src/types/payload.rs b/src/types/payload.rs
index 5b6cfb1..e6ddb0f 100644
--- a/src/types/payload.rs
+++ b/src/types/payload.rs
@@ -1,12 +1,16 @@
use crate::types::DateTime;
-#[derive(Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
+#[derive(Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, getset::Getters)]
pub struct Payload {
// TODO: Make this a mime::Mime, but as this type does not impl Serialize/Deserialize, we
// cannot do this trivially yet
+ #[getset(get = "pub")]
mime: String,
+ #[getset(get = "pub")]
timestamp: DateTime,
+
+ #[getset(get = "pub")]
content: crate::cid::Cid,
}