diff options
Diffstat (limited to 'openat/src/metadata.rs')
-rw-r--r-- | openat/src/metadata.rs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/openat/src/metadata.rs b/openat/src/metadata.rs new file mode 100644 index 0000000..de7cc22 --- /dev/null +++ b/openat/src/metadata.rs @@ -0,0 +1,75 @@ +use std::fs::Permissions; +use std::os::unix::fs::PermissionsExt; + +use libc; + +use crate::SimpleType; + + +/// A file metadata +/// +/// Because we can't freely create a `std::fs::Metadata` object we have to +/// implement our own structure. +pub struct Metadata { + stat: libc::stat, +} + +impl Metadata { + /// Returns simplified type of the directory entry + pub fn simple_type(&self) -> SimpleType { + let typ = self.stat.st_mode & libc::S_IFMT; + match typ { + libc::S_IFREG => SimpleType::File, + libc::S_IFDIR => SimpleType::Dir, + libc::S_IFLNK => SimpleType::Symlink, + _ => SimpleType::Other, + } + } + /// Returns underlying stat structure + pub fn stat(&self) -> &libc::stat { + &self.stat + } + /// Returns `true` if the entry is a regular file + pub fn is_file(&self) -> bool { + self.simple_type() == SimpleType::File + } + /// Returns `true` if the entry is a directory + pub fn is_dir(&self) -> bool { + self.simple_type() == SimpleType::Dir + } + /// Returns permissions of the entry + pub fn permissions(&self) -> Permissions { + Permissions::from_mode(self.stat.st_mode as u32) + } + /// Returns file size + pub fn len(&self) -> u64 { + self.stat.st_size as u64 + } +} + +pub fn new(stat: libc::stat) -> Metadata { + Metadata { stat: stat } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn dir() { + let d = crate::Dir::open(".").unwrap(); + let m = d.metadata("src").unwrap(); + assert_eq!(m.simple_type(), SimpleType::Dir); + assert!(m.is_dir()); + assert!(!m.is_file()); + } + + #[test] + fn file() { + let d = crate::Dir::open("src").unwrap(); + let m = d.metadata("lib.rs").unwrap(); + assert_eq!(m.simple_type(), SimpleType::File); + assert!(!m.is_dir()); + assert!(m.is_file()); + } +} |