use std::error::Error; use std::fmt; use std::fs; use std::io; use std::path::Path; use resources::Resource; use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner}; pub struct Dir> { path: D, } impl> Dir { pub fn new(path: D) -> Self { Self { path } } } impl> Symbol for Dir { fn target_reached(&self) -> Result> { if !self.path.as_ref().exists() { return Ok(false); } let metadata = fs::metadata(self.path.as_ref())?; if !metadata.is_dir() { return Err(Box::new(io::Error::new( io::ErrorKind::AlreadyExists, "Could not create a directory, non-directory file exists", ))); } Ok(true) } fn execute(&self) -> Result<(), Box> { fs::create_dir(self.path.as_ref()).map_err(|e| Box::new(e) as Box) } fn get_prerequisites(&self) -> Vec { if let Some(parent) = self.path.as_ref().parent() { vec![Resource::new("dir", parent.to_str().unwrap())] } else { vec![] } } fn provides(&self) -> Option> { Some(vec![Resource::new( "dir", self.path.as_ref().to_str().unwrap(), )]) } fn as_action<'a>(&'a self, runner: &'a dyn SymbolRunner) -> Box { Box::new(SymbolAction::new(runner, self)) } fn into_action<'a>(self: Box, runner: &'a dyn SymbolRunner) -> Box where Self: 'a, { Box::new(OwnedSymbolAction::new(runner, *self)) } } impl> fmt::Display for Dir { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "Dir {}", self.path.as_ref().display()) } }