use crate::ffi;
use std::time::SystemTime;
#[derive(Debug, Clone, Copy, Default)]
pub struct RequestedAttributes {
pub name: bool,
pub object_type: bool,
pub size: bool,
pub alloc_size: bool,
pub modified_time: bool,
pub permissions: bool,
pub inode: bool,
pub entry_count: bool,
}
impl RequestedAttributes {
pub fn all() -> Self {
Self {
name: true,
object_type: true,
size: true,
alloc_size: true,
modified_time: true,
permissions: true,
inode: true,
entry_count: true,
}
}
pub fn with_name(mut self) -> Self {
self.name = true;
self
}
pub fn with_object_type(mut self) -> Self {
self.object_type = true;
self
}
pub fn with_size(mut self) -> Self {
self.size = true;
self
}
pub fn with_alloc_size(mut self) -> Self {
self.alloc_size = true;
self
}
pub fn with_modified_time(mut self) -> Self {
self.modified_time = true;
self
}
pub fn with_permissions(mut self) -> Self {
self.permissions = true;
self
}
pub fn with_inode(mut self) -> Self {
self.inode = true;
self
}
pub fn with_entry_count(mut self) -> Self {
self.entry_count = true;
self
}
}
impl From<RequestedAttributes> for ffi::attrlist {
fn from(req: RequestedAttributes) -> Self {
let mut common = ffi::CommonAttr::RETURNED_ATTRS;
let mut file = ffi::FileAttr::empty();
let mut dir = ffi::DirAttr::empty();
if req.name {
common |= ffi::CommonAttr::NAME;
}
if req.object_type {
common |= ffi::CommonAttr::OBJTYPE;
}
if req.modified_time {
common |= ffi::CommonAttr::MODTIME;
}
if req.permissions {
common |= ffi::CommonAttr::ACCESSMASK;
}
if req.inode {
common |= ffi::CommonAttr::FILEID;
}
if req.size {
file |= ffi::FileAttr::TOTALSIZE;
}
if req.alloc_size {
file |= ffi::FileAttr::ALLOCSIZE;
}
if req.entry_count {
dir |= ffi::DirAttr::ENTRYCOUNT;
}
ffi::attrlist {
bitmapcount: ffi::ATTR_BIT_MAP_COUNT,
reserved: 0,
commonattr: common.bits(),
volattr: 0,
dirattr: dir.bits(),
fileattr: file.bits(),
forkattr: 0,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ObjectType {
Regular,
Directory,
Symlink,
BlockDevice,
CharDevice,
Socket,
Fifo,
Unknown(u32),
}
impl From<u32> for ObjectType {
fn from(vtype: u32) -> Self {
match vtype {
1 => ObjectType::Regular, 2 => ObjectType::Directory, 5 => ObjectType::Symlink, 3 => ObjectType::BlockDevice, 4 => ObjectType::CharDevice, 6 => ObjectType::Socket, 7 => ObjectType::Fifo, v => ObjectType::Unknown(v),
}
}
}
#[derive(Debug, Clone)]
pub struct DirEntry {
pub name: String,
pub object_type: Option<ObjectType>,
pub size: Option<u64>,
pub alloc_size: Option<u64>,
pub modified_time: Option<SystemTime>,
pub permissions: Option<u32>,
pub inode: Option<u64>,
pub entry_count: Option<u32>,
}
impl DirEntry {
pub fn is_dir(&self) -> bool {
self.object_type == Some(ObjectType::Directory)
}
pub fn is_file(&self) -> bool {
self.object_type == Some(ObjectType::Regular)
}
pub fn is_symlink(&self) -> bool {
self.object_type == Some(ObjectType::Symlink)
}
}