use std::error::Error; use std::fmt; use std::fs; use std::os::unix::fs::MetadataExt; use users::get_user_by_name; use symbols::Symbol; use symbols::dir::Dir; use command_runner::CommandRunner; pub struct DirFor<'a, D> where D: AsRef + fmt::Display { dir: Dir, path: D, user_name: &'a str, command_runner: &'a CommandRunner } impl<'a, D> DirFor<'a, D> where D: AsRef + fmt::Display + Clone { pub fn new(path: D, user_name: &'a str, command_runner: &'a CommandRunner) -> Self { DirFor { dir: Dir::new(path.clone()), path: path, user_name: user_name, command_runner: command_runner } } } impl<'a, D> Symbol for DirFor<'a, D> where D: AsRef + fmt::Display { fn target_reached(&self) -> Result> { match self.dir.target_reached() { Ok(true) => { let actual_uid = fs::metadata(self.path.as_ref()).unwrap().uid(); let target_uid = get_user_by_name(self.user_name).unwrap().uid(); Ok(actual_uid == target_uid) }, res => res } } fn execute(&self) -> Result<(), Box> { try!(self.dir.execute()); try!(self.command_runner.run_with_args("chown", &[self.user_name, self.path.as_ref()])); Ok(()) } } impl<'a, D> fmt::Display for DirFor<'a, D> where D: AsRef + fmt::Display { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ write!(f, "Dir {} for {}", self.path, self.user_name) } }