wip: initial hack of dag.resolve
This commit is contained in:
parent
f080ac9056
commit
efff60a41c
@ -45,7 +45,7 @@ where
|
||||
.or(warp::path!("bootstrap" / ..).and_then(not_implemented))
|
||||
.or(warp::path!("config" / ..).and_then(not_implemented))
|
||||
.or(dag::put(ipfs))
|
||||
//.or(dag::get(ipfs))
|
||||
.or(dag::resolve(ipfs))
|
||||
.or(warp::path!("dht" / ..).and_then(not_implemented))
|
||||
.or(warp::path!("get").and_then(not_implemented))
|
||||
.or(warp::path!("key" / ..).and_then(not_implemented))
|
||||
|
@ -68,3 +68,87 @@ pub fn put<T: IpfsTypes>(
|
||||
.and(multipart::form())
|
||||
.and_then(put_query)
|
||||
}
|
||||
|
||||
/// Per https://docs-beta.ipfs.io/reference/http/api/#api-v0-block-resolve this endpoint takes in a
|
||||
/// path and resolves it to the last block (the cid), and to the path inside the final block
|
||||
/// (rempath).
|
||||
pub fn resolve<T: IpfsTypes>(
|
||||
ipfs: &Ipfs<T>,
|
||||
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
path!("dag" / "resolve")
|
||||
.and(with_ipfs(ipfs))
|
||||
.and(query::<ResolveOptions>())
|
||||
.and_then(inner_resolve)
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ResolveOptions {
|
||||
arg: String,
|
||||
cid_base: Option<String>,
|
||||
}
|
||||
|
||||
async fn inner_resolve<T: IpfsTypes>(
|
||||
ipfs: Ipfs<T>,
|
||||
opts: ResolveOptions,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
use crate::v0::refs::{IpfsPath, WalkSuccess};
|
||||
use ipfs::Block;
|
||||
use libipld::block::decode_ipld;
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
let mut path = IpfsPath::try_from(opts.arg.as_str()).map_err(StringError::from)?;
|
||||
|
||||
let root = path.take_root().unwrap();
|
||||
|
||||
if path.len() == 0 {
|
||||
return Ok(reply::json(&json!({
|
||||
"Cid": { "/": root.to_string() },
|
||||
"RemPath": "",
|
||||
})));
|
||||
}
|
||||
|
||||
let mut current = root;
|
||||
let mut remaining = path
|
||||
.remaining_path()
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect::<VecDeque<_>>();
|
||||
|
||||
loop {
|
||||
let Block { data, .. } = ipfs.get_block(¤t).await.map_err(StringError::from)?;
|
||||
|
||||
let ipld = decode_ipld(¤t, &data).map_err(StringError::from)?;
|
||||
|
||||
let res = path.walk(¤t, ipld).map_err(StringError::from)?;
|
||||
|
||||
match res {
|
||||
WalkSuccess::EmptyPath(_) | WalkSuccess::AtDestination(_) => {
|
||||
let remaining = {
|
||||
let mut buf = String::with_capacity(
|
||||
remaining.iter().map(|s| s.len()).sum::<usize>() + remaining.len(),
|
||||
);
|
||||
while let Some(piece) = remaining.pop_front() {
|
||||
if !buf.is_empty() {
|
||||
buf.push('/');
|
||||
}
|
||||
buf.push_str(&piece);
|
||||
}
|
||||
buf
|
||||
};
|
||||
let response = json!({
|
||||
"Cid": { "/": current.to_string() },
|
||||
"RemPath": remaining,
|
||||
});
|
||||
return Ok(reply::json(&response));
|
||||
}
|
||||
WalkSuccess::Link(_key, next_cid) => {
|
||||
while remaining.len() > path.len() {
|
||||
remaining.pop_front();
|
||||
}
|
||||
|
||||
current = next_cid;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ mod format;
|
||||
use format::EdgeFormatter;
|
||||
|
||||
mod path;
|
||||
use path::{IpfsPath, WalkSuccess};
|
||||
pub use path::{IpfsPath, WalkSuccess};
|
||||
|
||||
mod unshared;
|
||||
use unshared::Unshared;
|
||||
@ -151,7 +151,10 @@ async fn refs_paths<T: IpfsTypes>(
|
||||
/// # Panics
|
||||
///
|
||||
/// If there are dag-pb nodes and the libipld has changed it's dag-pb tree structure.
|
||||
async fn walk_path<T: IpfsTypes>(ipfs: &Ipfs<T>, mut path: IpfsPath) -> Result<(Cid, Ipld), Error> {
|
||||
pub async fn walk_path<T: IpfsTypes>(
|
||||
ipfs: &Ipfs<T>,
|
||||
mut path: IpfsPath,
|
||||
) -> Result<(Cid, Ipld), Error> {
|
||||
let mut current = path.take_root().unwrap();
|
||||
|
||||
loop {
|
||||
|
@ -150,6 +150,10 @@ impl IpfsPath {
|
||||
Ok(WalkSuccess::AtDestination(ipld))
|
||||
}
|
||||
|
||||
pub fn remaining_path(&self) -> &[String] {
|
||||
self.path.as_slice()
|
||||
}
|
||||
|
||||
// Currently unused by commited code, but might become handy or easily removed later on.
|
||||
#[allow(dead_code)]
|
||||
pub fn debug<'a>(&'a self, current: &'a Cid) -> impl fmt::Debug + 'a {
|
||||
|
Loading…
Reference in New Issue
Block a user