ipld: IpldPath can be constructed from a String.

This commit is contained in:
David Craven 2019-02-23 23:57:35 +01:00
parent e2d2bc8541
commit 6cb07bb10e
No known key found for this signature in database
GPG Key ID: DF438712EA50DBB1
2 changed files with 51 additions and 0 deletions

View File

@ -7,6 +7,7 @@ use std::fmt::{self, Debug, Display};
pub enum IpldError {
UnsupportedCodec(Codec),
CodecError(Box<dyn CodecError>),
InvalidPath(String),
}
pub trait CodecError: Display + Debug + Error {}
@ -16,6 +17,7 @@ impl Error for IpldError {
match *self {
IpldError::UnsupportedCodec(_) => "unsupported codec",
IpldError::CodecError(_) => "codec error",
IpldError::InvalidPath(_) => "invalid path",
}
}
}
@ -29,6 +31,9 @@ impl Display for IpldError {
IpldError::CodecError(ref err) => {
write!(f, "{}", err)
}
IpldError::InvalidPath(ref path) => {
write!(f, "Invalid path {:?}", path)
}
}
}
}

View File

@ -1,5 +1,8 @@
use crate::block::Cid;
use crate::ipld::IpldError;
use std::sync::Arc;
#[derive(Clone, Debug, PartialEq)]
pub struct IpldPath {
root: Cid,
path: Vec<SubPath>,
@ -13,6 +16,28 @@ impl IpldPath {
}
}
pub fn from(string: &str) -> Result<Self, IpldError> {
let mut subpath = string.split("/");
if subpath.next() != Some("") {
return Err(IpldError::InvalidPath(string.to_owned()));
}
let cid_string = subpath.next();
if cid_string.is_none() {
return Err(IpldError::InvalidPath(string.to_owned()));
}
let cid = Arc::new(cid::Cid::from(cid_string.unwrap())?);
let mut path = IpldPath::new(cid);
for sub_path in subpath {
let index = sub_path.parse::<usize>();
if index.is_ok() {
path.push(index.unwrap());
} else {
path.push(sub_path);
}
}
Ok(path)
}
pub fn root(&self) -> Cid {
self.root.to_owned()
}
@ -37,6 +62,7 @@ impl IpldPath {
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum SubPath {
Key(String),
Index(usize),
@ -102,6 +128,26 @@ mod tests {
use super::*;
use crate::block::Block;
#[test]
fn test_from_string() {
let string = "/QmRN6wdp1S2A5EtjW9A3M1vKSBuQQGcgvuhoMUoEz4iiT5/key/3";
let res = IpldPath::from(string).unwrap();
let cid = Block::from("hello").cid();
let mut path = IpldPath::new(cid);
path.push("key");
path.push(3);
assert_eq!(path, res);
}
#[test]
fn test_from_string_errors() {
assert!(IpldPath::from("").is_err());
assert!(IpldPath::from("/").is_err());
assert!(IpldPath::from("/QmRN").is_err());
}
#[test]
fn test_to_string() {
let cid = Block::from("hello").cid();