From c6952cb074af15db824668e223e6054127cf0e18 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 5 Aug 2020 12:31:52 +0200 Subject: [PATCH 1/2] feat: make IpldDag an async_trait Signed-off-by: ljedrz --- src/dag.rs | 29 ++++++++++++++--------------- src/lib.rs | 15 +++++---------- src/unixfs/mod.rs | 10 +++++----- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/dag.rs b/src/dag.rs index 4202b3d62..5062d2e8c 100644 --- a/src/dag.rs +++ b/src/dag.rs @@ -1,23 +1,22 @@ use crate::error::Error; use crate::path::{IpfsPath, IpfsPathError, SubPath}; -use crate::repo::RepoTypes; -use crate::Ipfs; +use crate::repo::{Repo, RepoTypes}; +use async_trait::async_trait; use bitswap::Block; use cid::{Cid, Codec, Version}; use libipld::block::{decode_ipld, encode_ipld}; use libipld::ipld::Ipld; -#[derive(Clone, Debug)] -pub struct IpldDag { - ipfs: Ipfs, -} +#[async_trait] +pub trait IpldDag { + async fn put_dag(&self, data: Ipld, codec: Codec) -> Result; -impl IpldDag { - pub fn new(ipfs: Ipfs) -> Self { - IpldDag { ipfs } - } + async fn get_dag(&self, path: IpfsPath) -> Result; +} - pub async fn put(&self, data: Ipld, codec: Codec) -> Result { +#[async_trait] +impl IpldDag for Repo { + async fn put_dag(&self, data: Ipld, codec: Codec) -> Result { let bytes = encode_ipld(&data, codec)?; let hash = multihash::Sha2_256::digest(&bytes); let version = if codec == Codec::DagProtobuf { @@ -27,16 +26,16 @@ impl IpldDag { }; let cid = Cid::new(version, codec, hash)?; let block = Block::new(bytes, cid); - let (cid, _) = self.ipfs.repo.put_block(block).await?; + let (cid, _) = self.put_block(block).await?; Ok(cid) } - pub async fn get(&self, path: IpfsPath) -> Result { + async fn get_dag(&self, path: IpfsPath) -> Result { let cid = match path.root().cid() { Some(cid) => cid, None => return Err(anyhow::anyhow!("expected cid")), }; - let mut ipld = decode_ipld(&cid, self.ipfs.repo.get_block(&cid).await?.data())?; + let mut ipld = decode_ipld(&cid, self.get_block(&cid).await?.data())?; for sub_path in path.iter() { if !can_resolve(&ipld, sub_path) { let path = sub_path.to_owned(); @@ -44,7 +43,7 @@ impl IpldDag { } ipld = resolve(ipld, sub_path); ipld = match ipld { - Ipld::Link(cid) => decode_ipld(&cid, self.ipfs.repo.get_block(&cid).await?.data())?, + Ipld::Link(cid) => decode_ipld(&cid, self.get_block(&cid).await?.data())?, ipld => ipld, }; } diff --git a/src/lib.rs b/src/lib.rs index 60201d8bf..0372115d7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -350,10 +350,6 @@ impl std::ops::Deref for Ipfs { } impl Ipfs { - fn dag(&self) -> IpldDag { - IpldDag::new(self.clone()) - } - fn ipns(&self) -> Ipns { Ipns::new(self.clone()) } @@ -401,23 +397,22 @@ impl Ipfs { /// Puts an ipld dag node into the ipfs repo. pub async fn put_dag(&self, ipld: Ipld) -> Result { - self.dag() - .put(ipld, Codec::DagCBOR) + self.repo + .put_dag(ipld, Codec::DagCBOR) .instrument(self.span.clone()) .await } /// Gets an ipld dag node from the ipfs repo. pub async fn get_dag(&self, path: IpfsPath) -> Result { - self.dag().get(path).instrument(self.span.clone()).await + self.repo.get_dag(path).instrument(self.span.clone()).await } /// Adds a file into the ipfs repo. pub async fn add(&self, path: PathBuf) -> Result { - let dag = self.dag(); let file = File::new(path).await?; let path = file - .put_unixfs_v1(&dag) + .put_unixfs_v1(&self.repo) .instrument(self.span.clone()) .await?; Ok(path) @@ -425,7 +420,7 @@ impl Ipfs { /// Gets a file from the ipfs repo. pub async fn get(&self, path: IpfsPath) -> Result { - File::get_unixfs_v1(&self.dag(), path) + File::get_unixfs_v1(&self.repo, path) .instrument(self.span.clone()) .await } diff --git a/src/unixfs/mod.rs b/src/unixfs/mod.rs index 797864cb9..91f39c4d0 100644 --- a/src/unixfs/mod.rs +++ b/src/unixfs/mod.rs @@ -1,7 +1,7 @@ use crate::dag::IpldDag; use crate::error::Error; use crate::path::IpfsPath; -use crate::repo::RepoTypes; +use crate::repo::{Repo, RepoTypes}; use async_std::fs; use async_std::io::ReadExt; use async_std::path::PathBuf; @@ -31,20 +31,20 @@ impl File { } pub async fn get_unixfs_v1( - dag: &IpldDag, + repo: &Repo, path: IpfsPath, ) -> Result { - let ipld = dag.get(path).await?; + let ipld = repo.get_dag(path).await?; let pb_node: PbNode = (&ipld).try_into()?; Ok(File { data: pb_node.data }) } - pub async fn put_unixfs_v1(&self, dag: &IpldDag) -> Result { + pub async fn put_unixfs_v1(&self, repo: &Repo) -> Result { let links: Vec = vec![]; let mut pb_node = BTreeMap::::new(); pb_node.insert("Data".to_string(), self.data.clone().into()); pb_node.insert("Links".to_string(), links.into()); - dag.put(pb_node.into(), Codec::DagProtobuf).await + repo.put_dag(pb_node.into(), Codec::DagProtobuf).await } } From aca0b14c92deab71e4ac4d7b578e2a5415017822 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 5 Aug 2020 12:35:16 +0200 Subject: [PATCH 2/2] feat: make Ipns an async_trait Signed-off-by: ljedrz --- src/dag.rs | 35 +++++++++++++++-------------------- src/ipns/mod.rs | 33 +++++++++++++++++---------------- src/lib.rs | 17 ++++++++--------- src/unixfs/mod.rs | 3 +-- 4 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/dag.rs b/src/dag.rs index 5062d2e8c..282976281 100644 --- a/src/dag.rs +++ b/src/dag.rs @@ -99,21 +99,19 @@ mod tests { #[async_std::test] async fn test_resolve_root_cid() { let Node { ipfs, bg_task: _bt } = Node::new("test_node").await; - let dag = IpldDag::new(ipfs); let data = ipld!([1, 2, 3]); - let cid = dag.put(data.clone(), Codec::DagCBOR).await.unwrap(); - let res = dag.get(IpfsPath::from(cid)).await.unwrap(); + let cid = ipfs.put_dag(data.clone()).await.unwrap(); + let res = ipfs.get_dag(IpfsPath::from(cid)).await.unwrap(); assert_eq!(res, data); } #[async_std::test] async fn test_resolve_array_elem() { let Node { ipfs, bg_task: _bt } = Node::new("test_node").await; - let dag = IpldDag::new(ipfs); let data = ipld!([1, 2, 3]); - let cid = dag.put(data.clone(), Codec::DagCBOR).await.unwrap(); - let res = dag - .get(IpfsPath::from(cid).sub_path("1").unwrap()) + let cid = ipfs.put_dag(data.clone()).await.unwrap(); + let res = ipfs + .get_dag(IpfsPath::from(cid).sub_path("1").unwrap()) .await .unwrap(); assert_eq!(res, ipld!(2)); @@ -122,11 +120,10 @@ mod tests { #[async_std::test] async fn test_resolve_nested_array_elem() { let Node { ipfs, bg_task: _bt } = Node::new("test_node").await; - let dag = IpldDag::new(ipfs); let data = ipld!([1, [2], 3,]); - let cid = dag.put(data, Codec::DagCBOR).await.unwrap(); - let res = dag - .get(IpfsPath::from(cid).sub_path("1/0").unwrap()) + let cid = ipfs.put_dag(data).await.unwrap(); + let res = ipfs + .get_dag(IpfsPath::from(cid).sub_path("1/0").unwrap()) .await .unwrap(); assert_eq!(res, ipld!(2)); @@ -135,13 +132,12 @@ mod tests { #[async_std::test] async fn test_resolve_object_elem() { let Node { ipfs, bg_task: _bt } = Node::new("test_node").await; - let dag = IpldDag::new(ipfs); let data = ipld!({ "key": false, }); - let cid = dag.put(data, Codec::DagCBOR).await.unwrap(); - let res = dag - .get(IpfsPath::from(cid).sub_path("key").unwrap()) + let cid = ipfs.put_dag(data).await.unwrap(); + let res = ipfs + .get_dag(IpfsPath::from(cid).sub_path("key").unwrap()) .await .unwrap(); assert_eq!(res, ipld!(false)); @@ -150,13 +146,12 @@ mod tests { #[async_std::test] async fn test_resolve_cid_elem() { let Node { ipfs, bg_task: _bt } = Node::new("test_node").await; - let dag = IpldDag::new(ipfs); let data1 = ipld!([1]); - let cid1 = dag.put(data1, Codec::DagCBOR).await.unwrap(); + let cid1 = ipfs.put_dag(data1).await.unwrap(); let data2 = ipld!([cid1]); - let cid2 = dag.put(data2, Codec::DagCBOR).await.unwrap(); - let res = dag - .get(IpfsPath::from(cid2).sub_path("0/0").unwrap()) + let cid2 = ipfs.put_dag(data2).await.unwrap(); + let res = ipfs + .get_dag(IpfsPath::from(cid2).sub_path("0/0").unwrap()) .await .unwrap(); assert_eq!(res, ipld!(1)); diff --git a/src/ipns/mod.rs b/src/ipns/mod.rs index df9619e37..81ecfda16 100644 --- a/src/ipns/mod.rs +++ b/src/ipns/mod.rs @@ -1,8 +1,8 @@ #![allow(dead_code)] use crate::error::Error; use crate::path::{IpfsPath, PathRoot}; -use crate::repo::RepoTypes; -use crate::Ipfs; +use crate::repo::{Repo, RepoTypes}; +use async_trait::async_trait; use libp2p::PeerId; mod dns; @@ -11,22 +11,23 @@ mod ipns_pb { include!(concat!(env!("OUT_DIR"), "/ipns_pb.rs")); } -#[derive(Clone, Debug)] -pub struct Ipns { - ipfs: Ipfs, -} +#[async_trait] +pub trait Ipns { + async fn resolve_ipns(&self, path: &IpfsPath) -> Result; -impl Ipns { - pub fn new(ipfs: Ipfs) -> Self { - Ipns { ipfs } - } + async fn publish_ipns(&self, key: &PeerId, path: &IpfsPath) -> Result; + + async fn cancel_ipns(&self, key: &PeerId) -> Result<(), Error>; +} +#[async_trait] +impl Ipns for Repo { /// Resolves a ipns path to an ipld path. - pub async fn resolve(&self, path: &IpfsPath) -> Result { + async fn resolve_ipns(&self, path: &IpfsPath) -> Result { let path = path.to_owned(); match path.root() { PathRoot::Ipld(_) => Ok(path), - PathRoot::Ipns(peer_id) => match self.ipfs.repo.get_ipns(peer_id).await? { + PathRoot::Ipns(peer_id) => match self.get_ipns(peer_id).await? { Some(path) => Ok(path), None => Err(anyhow::anyhow!("unimplemented")), }, @@ -35,8 +36,8 @@ impl Ipns { } /// Publishes an ipld path. - pub async fn publish(&self, key: &PeerId, path: &IpfsPath) -> Result { - let future = self.ipfs.repo.put_ipns(key, path); + async fn publish_ipns(&self, key: &PeerId, path: &IpfsPath) -> Result { + let future = self.put_ipns(key, path); let key = key.to_owned(); let mut path = path.to_owned(); future.await?; @@ -45,8 +46,8 @@ impl Ipns { } /// Cancel an ipns path. - pub async fn cancel(&self, key: &PeerId) -> Result<(), Error> { - self.ipfs.repo.remove_ipns(key).await?; + async fn cancel_ipns(&self, key: &PeerId) -> Result<(), Error> { + self.remove_ipns(key).await?; Ok(()) } } diff --git a/src/lib.rs b/src/lib.rs index 0372115d7..86737fa17 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -350,10 +350,6 @@ impl std::ops::Deref for Ipfs { } impl Ipfs { - fn ipns(&self) -> Ipns { - Ipns::new(self.clone()) - } - /// Puts a block into the ipfs repo. pub async fn put_block(&self, block: Block) -> Result { self.repo @@ -445,23 +441,26 @@ impl Ipfs { /// Resolves a ipns path to an ipld path. pub async fn resolve_ipns(&self, path: &IpfsPath) -> Result { - self.ipns() - .resolve(path) + self.repo + .resolve_ipns(path) .instrument(self.span.clone()) .await } /// Publishes an ipld path. pub async fn publish_ipns(&self, key: &PeerId, path: &IpfsPath) -> Result { - self.ipns() - .publish(key, path) + self.repo + .publish_ipns(key, path) .instrument(self.span.clone()) .await } /// Cancel an ipns path. pub async fn cancel_ipns(&self, key: &PeerId) -> Result<(), Error> { - self.ipns().cancel(key).instrument(self.span.clone()).await + self.repo + .cancel_ipns(key) + .instrument(self.span.clone()) + .await } pub async fn connect>(&self, target: T) -> Result<(), Error> { diff --git a/src/unixfs/mod.rs b/src/unixfs/mod.rs index 91f39c4d0..02de1f085 100644 --- a/src/unixfs/mod.rs +++ b/src/unixfs/mod.rs @@ -77,11 +77,10 @@ mod tests { #[async_std::test] async fn test_file_cid() { let Node { ipfs, bg_task: _bt } = Node::new("test_node").await; - let dag = IpldDag::new(ipfs); let file = File::from("\u{8}\u{2}\u{12}\u{12}Here is some data\n\u{18}\u{12}"); let cid = Cid::try_from("QmSy5pnHk1EnvE5dmJSyFKG5unXLGjPpBuJJCBQkBTvBaW").unwrap(); - let cid2 = file.put_unixfs_v1(&dag).await.unwrap(); + let cid2 = file.put_unixfs_v1(&ipfs.repo).await.unwrap(); assert_eq!(cid.to_string(), cid2.to_string()); } }