#![warn(rust_2018_idioms)]
extern crate alloc;
use alloc::borrow::Cow;
use core::fmt;
pub mod file;
pub mod symlink;
pub mod dir;
pub use dir::{resolve, LookupError, MaybeResolved, ResolveError};
mod pb;
pub use pb::{FlatUnixFs, PBLink, PBNode, UnixFs, UnixFsType};
pub mod dagpb;
pub mod walk;
#[cfg(test)]
pub(crate) mod test_support;
#[derive(Debug)]
pub struct InvalidCidInLink {
pub nth: usize,
pub hash: Cow<'static, [u8]>,
pub name: Cow<'static, str>,
pub source: libipld::cid::Error,
#[allow(dead_code)]
hidden: (),
}
impl<'a> From<(usize, pb::PBLink<'a>, libipld::cid::Error)> for InvalidCidInLink {
fn from((nth, link, source): (usize, pb::PBLink<'a>, libipld::cid::Error)) -> Self {
let hash = match link.Hash {
Some(Cow::Borrowed(x)) if !x.is_empty() => Cow::Owned(x.to_vec()),
Some(Cow::Borrowed(_)) | None => Cow::Borrowed(&[][..]),
Some(Cow::Owned(x)) => Cow::Owned(x),
};
let name = match link.Name {
Some(Cow::Borrowed(x)) if !x.is_empty() => Cow::Owned(x.to_string()),
Some(Cow::Borrowed(_)) | None => Cow::Borrowed(""),
Some(Cow::Owned(x)) => Cow::Owned(x),
};
InvalidCidInLink {
nth,
hash,
name,
source,
hidden: (),
}
}
}
impl fmt::Display for InvalidCidInLink {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
fmt,
"failed to convert link #{} ({:?}) to Cid: {}",
self.nth, self.name, self.source
)
}
}
impl std::error::Error for InvalidCidInLink {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.source)
}
}
pub struct UnexpectedNodeType(i32);
impl fmt::Debug for UnexpectedNodeType {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let converted = UnixFsType::from(self.0);
if converted == UnixFsType::Raw && self.0 != 0 {
write!(fmt, "{} or <unknown>", self.0)
} else {
write!(fmt, "{} or {:?}", self.0, converted)
}
}
}
impl From<UnixFsType> for UnexpectedNodeType {
fn from(t: UnixFsType) -> UnexpectedNodeType {
UnexpectedNodeType(t.into())
}
}
impl UnexpectedNodeType {
pub fn is_directory(&self) -> bool {
matches!(
UnixFsType::from(self.0),
UnixFsType::Directory | UnixFsType::HAMTShard
)
}
pub fn is_file(&self) -> bool {
matches!(UnixFsType::from(self.0), UnixFsType::File)
}
}
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct Metadata {
mode: Option<u32>,
mtime: Option<(i64, u32)>,
}
impl Metadata {
pub fn mode(&self) -> Option<u32> {
self.mode
}
pub fn mtime(&self) -> Option<(i64, u32)> {
self.mtime
}
#[cfg(feature = "filetime")]
pub fn mtime_as_filetime(&self) -> Option<filetime::FileTime> {
self.mtime()
.map(|(seconds, nanos)| filetime::FileTime::from_unix_time(seconds, nanos))
}
}
impl<'a> From<&'a UnixFs<'_>> for Metadata {
fn from(data: &'a UnixFs<'_>) -> Self {
let mode = data.mode;
let mtime = data
.mtime
.clone()
.map(|ut| (ut.Seconds, ut.FractionalNanoseconds.unwrap_or(0)));
Metadata { mode, mtime }
}
}