feat: add follow_dagpb_data option to ipfspath

This commit is contained in:
Joonas Koivunen 2020-06-16 16:49:46 +03:00
parent 8ada8370c4
commit cbd2d4a992
3 changed files with 22 additions and 12 deletions

View File

@ -360,7 +360,7 @@ fn handle_dagpb_not_found(
needle: String,
path: &IpfsPath,
) -> Result<(Cid, Loaded, Vec<String>), WalkError> {
if needle == "Data" && path.len() == 0 {
if needle == "Data" && path.len() == 0 && path.follow_dagpb_data() {
// /dag/resolve needs to "resolve through" a dag-pb node down to the "just
// data" even though we do not need to extract it ... however this might be
// good to just filter with refs, as no refs of such path exist

View File

@ -34,6 +34,9 @@ pub struct IpfsPath {
/// Option to support moving the cid
root: Option<Cid>,
path: std::vec::IntoIter<String>,
/// True by default, to allow "finding" `Data` under dag-pb node
/// TODO: document why this matters
follow_dagpb_data: bool,
}
impl From<Cid> for IpfsPath {
@ -43,6 +46,7 @@ impl From<Cid> for IpfsPath {
IpfsPath {
root: Some(root),
path: Vec::new().into_iter(),
follow_dagpb_data: true,
}
}
}
@ -90,7 +94,9 @@ impl TryFrom<&str> for IpfsPath {
let root = Some(Cid::try_from(root).map_err(PathError::InvalidCid)?);
Ok(IpfsPath { root, path })
let follow_dagpb_data = true;
Ok(IpfsPath { root, path, follow_dagpb_data })
}
}
@ -99,6 +105,14 @@ impl IpfsPath {
self.root.take()
}
pub fn set_follow_dagpb_data(&mut self, follow: bool) {
self.follow_dagpb_data = follow;
}
pub fn follow_dagpb_data(&self) -> bool {
self.follow_dagpb_data
}
pub fn resolve(&mut self, ipld: Ipld) -> Result<WalkSuccess, WalkFailed> {
let key = match self.next() {
Some(key) => key,

View File

@ -1,7 +1,7 @@
use crate::v0::support::unshared::Unshared;
use crate::v0::support::{with_ipfs, StreamResponse, StringError};
use ipfs::{Ipfs, IpfsTypes};
use libipld::cid::Codec;
use libipld::cid::{Cid, Codec};
use serde::Deserialize;
use std::borrow::Cow;
use std::convert::TryFrom;
@ -37,7 +37,8 @@ pub fn cat<T: IpfsTypes>(
async fn cat_inner<T: IpfsTypes>(ipfs: Ipfs<T>, args: CatArgs) -> Result<impl Reply, Rejection> {
let path = IpfsPath::try_from(args.arg.as_str()).map_err(StringError::from)?;
let mut path = IpfsPath::try_from(args.arg.as_str()).map_err(StringError::from)?;
path.set_follow_dagpb_data(false);
let range = match (args.offset, args.length) {
(Some(start), Some(len)) => Some(start..(start + len)),
@ -85,24 +86,19 @@ pub fn get<T: IpfsTypes>(
async fn get_inner<T: IpfsTypes>(ipfs: Ipfs<T>, args: GetArgs) -> Result<impl Reply, Rejection> {
let path = IpfsPath::try_from(args.arg.as_str()).map_err(StringError::from)?;
let mut path = IpfsPath::try_from(args.arg.as_str()).map_err(StringError::from)?;
path.set_follow_dagpb_data(false);
// FIXME: this is here until we have IpfsPath back at ipfs
// FIXME: use the second tuple value
let (cid, _, _) = walk_path(&ipfs, path).await.map_err(StringError::from)?;
if cid.codec() != Codec::DagProtobuf {
return Err(StringError::from("unknown node type").into());
}
let st = walk(ipfs, cid);
Ok(StreamResponse(Unshared::new(st)))
Ok(StreamResponse(Unshared::new(walk(ipfs, cid))))
}
use libipld::cid::Cid;
fn walk<Types: IpfsTypes>(ipfs: Ipfs<Types>, root: Cid)
-> impl Stream<Item = Result<Bytes, std::convert::Infallible>> + 'static
{