use std::time::Duration;
use crate::{path::PathComponent, B3Digest, Node};
#[derive(Clone, Debug)]
pub enum InodeData {
Regular(B3Digest, u64, bool), Symlink(bytes::Bytes), Directory(DirectoryInodeData), }
#[derive(Clone, Debug)]
pub enum DirectoryInodeData {
Sparse(B3Digest, u64), Populated(B3Digest, Vec<(u64, PathComponent, Node)>), }
impl InodeData {
pub fn from_node(node: &Node) -> Self {
match node {
Node::Directory { digest, size } => {
Self::Directory(DirectoryInodeData::Sparse(digest.clone(), *size))
}
Node::File {
digest,
size,
executable,
} => Self::Regular(digest.clone(), *size, *executable),
Node::Symlink { target } => Self::Symlink(target.clone().into()),
}
}
pub fn as_fuse_file_attr(&self, inode: u64) -> fuse_backend_rs::abi::fuse_abi::Attr {
fuse_backend_rs::abi::fuse_abi::Attr {
ino: inode,
blocks: 1024,
size: match self {
InodeData::Regular(_, size, _) => *size,
InodeData::Symlink(target) => target.len() as u64,
InodeData::Directory(DirectoryInodeData::Sparse(_, size)) => *size,
InodeData::Directory(DirectoryInodeData::Populated(_, ref children)) => {
children.len() as u64
}
},
mode: self.as_fuse_type() | self.mode(),
..Default::default()
}
}
fn mode(&self) -> u32 {
match self {
InodeData::Regular(_, _, false) | InodeData::Symlink(_) => 0o444,
InodeData::Regular(_, _, true) | InodeData::Directory(_) => 0o555,
}
}
pub fn as_fuse_entry(&self, inode: u64) -> fuse_backend_rs::api::filesystem::Entry {
fuse_backend_rs::api::filesystem::Entry {
inode,
attr: self.as_fuse_file_attr(inode).into(),
attr_timeout: Duration::MAX,
entry_timeout: Duration::MAX,
..Default::default()
}
}
pub fn as_fuse_type(&self) -> u32 {
#[allow(clippy::let_and_return)]
let ty = match self {
InodeData::Regular(_, _, _) => libc::S_IFREG,
InodeData::Symlink(_) => libc::S_IFLNK,
InodeData::Directory(_) => libc::S_IFDIR,
};
#[cfg(target_os = "macos")]
let ty = ty as u32;
ty
}
}