use std::path::PathBuf;
use crate::errors::RvResult;
pub struct Chown
{
pub(crate) opts: ChownOpts,
pub(crate) exec: Box<dyn Fn(ChownOpts) -> RvResult<()>>, }
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct ChownOpts
{
pub(crate) path: PathBuf, pub(crate) uid: Option<u32>, pub(crate) gid: Option<u32>, pub(crate) follow: bool, pub(crate) recursive: bool, }
impl Chown
{
pub fn uid(mut self, uid: u32) -> Self
{
self.opts.uid = Some(uid);
self
}
pub fn gid(mut self, gid: u32) -> Self
{
self.opts.gid = Some(gid);
self
}
pub fn owner(mut self, uid: u32, gid: u32) -> Self
{
self.opts.uid = Some(uid);
self.opts.gid = Some(gid);
self
}
pub fn follow(mut self) -> Self
{
self.opts.follow = true;
self
}
pub fn recurse(mut self, yes: bool) -> Self
{
self.opts.recursive = yes;
self
}
pub fn exec(&self) -> RvResult<()>
{
(self.exec)(self.opts.clone())
}
}
#[cfg(test)]
mod tests
{
use crate::prelude::*;
#[test]
fn test_vfs_chown()
{
test_chown(assert_vfs_setup!(Vfs::memfs()));
test_chown(assert_vfs_setup!(Vfs::stdfs()));
}
fn test_chown((vfs, tmpdir): (Vfs, PathBuf))
{
let dir1 = tmpdir.mash("dir1");
let file1 = tmpdir.mash("file1");
let dir1file1 = dir1.mash("dir1file1");
assert_vfs_mkfile!(vfs, &file1);
assert_vfs_mkdir_p!(vfs, &dir1);
assert_vfs_mkfile!(vfs, &dir1file1);
let (uid, gid) = vfs.owner(&file1).unwrap();
assert!(vfs.chown(&file1, uid, gid).is_ok());
assert_eq!(vfs.uid(&file1).unwrap(), uid);
assert_eq!(vfs.gid(&file1).unwrap(), gid);
assert!(vfs.chown(&dir1, uid, gid).is_ok());
assert_eq!(vfs.owner(&dir1).unwrap(), (uid, gid));
assert_eq!(vfs.owner(&dir1file1).unwrap(), (uid, gid));
assert_vfs_remove_all!(vfs, &tmpdir);
}
#[test]
fn test_vfs_chown_follow()
{
test_chown_follow(assert_vfs_setup!(Vfs::memfs()));
test_chown_follow(assert_vfs_setup!(Vfs::stdfs()));
}
fn test_chown_follow((vfs, tmpdir): (Vfs, PathBuf))
{
let dir1 = tmpdir.mash("dir1");
let dir1file1 = dir1.mash("dir1file1");
let link1 = tmpdir.mash("link1");
assert_vfs_mkdir_p!(vfs, &dir1);
assert_vfs_mkfile!(vfs, &dir1file1);
assert_vfs_symlink!(vfs, &link1, &dir1);
let (uid, gid) = vfs.owner(&dir1file1).unwrap();
assert!(vfs.chown_b(&link1).unwrap().owner(uid, gid).exec().is_ok());
assert_eq!(vfs.owner(&dir1).unwrap(), (uid, gid));
assert_eq!(vfs.owner(&dir1file1).unwrap(), (uid, gid));
assert!(vfs.chown_b(&link1).unwrap().owner(uid, gid).exec().is_ok());
assert_eq!(vfs.owner(&dir1).unwrap(), (uid, gid));
assert_eq!(vfs.owner(&dir1file1).unwrap(), (uid, gid));
assert_vfs_remove_all!(vfs, &tmpdir);
}
}