use crate::tasks::*;
use crate::handle::handle::TaskHandle;
use crate::tasks::fields::Field;
use crate::tasks::files::Recurse;
use serde::{Deserialize};
use std::sync::Arc;
use std::vec::Vec;
const MODULE: &str = "directory";
#[derive(Deserialize,Debug)]
#[serde(deny_unknown_fields)]
pub struct DirectoryTask {
pub name: Option<String>,
pub path: String,
pub remove: Option<String>,
pub recurse: Option<String>,
pub attributes: Option<FileAttributesInput>,
pub with: Option<PreLogicInput>,
pub and: Option<PostLogicInput>
}
struct DirectoryAction {
pub path: String,
pub remove: bool,
pub recurse: Recurse,
pub attributes: Option<FileAttributesEvaluated>,
}
impl IsTask for DirectoryTask {
fn get_module(&self) -> String { String::from(MODULE) }
fn get_name(&self) -> Option<String> { self.name.clone() }
fn get_with(&self) -> Option<PreLogicInput> { self.with.clone() }
fn evaluate(&self, handle: &Arc<TaskHandle>, request: &Arc<TaskRequest>, tm: TemplateMode) -> Result<EvaluatedTask, Arc<TaskResponse>> {
let recurse = match handle.template.boolean_option_default_false(&request, tm, &String::from("recurse"), &self.recurse)? {
true => Recurse::Yes,
false => Recurse::No
};
return Ok(
EvaluatedTask {
action: Arc::new(DirectoryAction {
remove: handle.template.boolean_option_default_false(&request, tm, &String::from("remove"), &self.remove)?,
recurse: recurse,
path: handle.template.path(&request, tm, &String::from("path"), &self.path)?,
attributes: FileAttributesInput::template(&handle, &request, tm, &self.attributes)?
}),
with: Arc::new(PreLogicInput::template(&handle, &request, tm, &self.with)?),
and: Arc::new(PostLogicInput::template(&handle, &request, tm, &self.and)?),
}
);
}
}
impl IsAction for DirectoryAction {
fn dispatch(&self, handle: &Arc<TaskHandle>, request: &Arc<TaskRequest>) -> Result<Arc<TaskResponse>, Arc<TaskResponse>> {
match request.request_type {
TaskRequestType::Query => {
let mut changes : Vec<Field> = Vec::new();
let remote_mode = handle.remote.query_common_file_attributes(request, &self.path, &self.attributes, &mut changes, self.recurse)?;
if remote_mode.is_none() {
if self.remove { return Ok(handle.response.is_matched(request)); }
else { return Ok(handle.response.needs_creation(request)); }
} else {
let is_file = handle.remote.get_is_file(request, &self.path)?;
if is_file { return Err(handle.response.is_failed(request, &format!("{} is not a directory", self.path))); }
else if self.remove { return Ok(handle.response.needs_removal(request)); }
else if changes.is_empty() { return Ok(handle.response.is_matched(request)); }
else { return Ok(handle.response.needs_modification(request, &changes)); }
}
},
TaskRequestType::Create => {
handle.remote.create_directory(request, &self.path)?;
handle.remote.process_all_common_file_attributes(request, &self.path, &self.attributes, self.recurse)?;
return Ok(handle.response.is_created(request));
},
TaskRequestType::Modify => {
handle.remote.process_common_file_attributes(request, &self.path, &self.attributes, &request.changes, self.recurse)?;
return Ok(handle.response.is_modified(request, request.changes.clone()));
},
TaskRequestType::Remove => {
handle.remote.delete_directory(request, &self.path, self.recurse)?;
return Ok(handle.response.is_removed(request))
}
_ => { return Err(handle.response.not_supported(request)); }
}
}
}