diff options
author | Malte Brandy <malte.brandy@maralorn.de> | 2018-04-28 02:05:39 +0200 |
---|---|---|
committer | Malte Brandy <malte.brandy@maralorn.de> | 2018-04-28 02:05:39 +0200 |
commit | 46c9383dc3c205bcf70eba201e711f0b4ea4af71 (patch) | |
tree | 60db592908989bc15eeac9be43d864bdada00661 /src | |
parent | 804593f7ea7e45f3a04a78a8715410b6ba2201ae (diff) |
Make tw module more flexible
As recommended this commit separates the save and query functions into
multiple functions, where the user can always supply their own Command.
The save process can return a Child struct if wanted.
This is a poor mans future for now.
Diffstat (limited to 'src')
-rw-r--r-- | src/tw.rs | 64 |
1 files changed, 42 insertions, 22 deletions
@@ -11,48 +11,68 @@ use error::{Result, ResultExt, ErrorKind as EK}; use task::Task; -use std::process::{Command, Stdio}; +use std::process::{Command, Stdio, Child}; use std::io::Write; +use std::iter::once; use import::import; use serde_json; /// This will give you all tasks which match the given query in the taskwarrior query syntax. /// This is not sanitized. Never get the query string from an untrusted user. pub fn query(query: &str) -> Result<Vec<Task>> { - let mut cmd = Command::new("task"); - for filter in query.split_whitespace() { - cmd.arg(filter); + let mut cmd = add_query_to_cmd(query, Command::new("task")); + cmd.stdout(Stdio::piped()); + run_query_cmd(cmd) +} + +/// This will take a Command, and append the given query string splited at whitespace followed by +/// the "export" command to the arguments of the Command. +pub fn add_query_to_cmd(query: &str, mut cmd: Command) -> Command { + for x in query.split_whitespace().chain(once("export")) { + cmd.arg(x); } - let mut export = cmd.arg("export").stdout(Stdio::piped()).spawn().chain_err( - || { - EK::TaskCmdError - }, - )?; + cmd +} + +/// This executes the given Command and trys to convert the Result into a Vec<Task>. +pub fn run_query_cmd(mut cmd: Command) -> Result<Vec<Task>> { + let mut export = cmd.spawn().chain_err(|| EK::TaskCmdError)?; export.wait().chain_err(|| EK::TaskCmdError)?; import(export.stdout.chain_err(|| EK::TaskCmdError)?) } -/// This will save the given tasks to taskwarrior. Call with `Some(task)` if you just have one -/// task. -pub fn save<T>(tasks: T) -> Result<()> -where - T: IntoIterator<Item = Task>, -{ - let tasks: Vec<Task> = tasks.into_iter().collect(); +/// This function runs the given Command, pipes the tasks as JSON to it and returns a handle to the child process. +pub fn save_to_cmd<'a>(tasks: Vec<&'a Task>, mut cmd: Command) -> Result<Child> { let input_buffer = serde_json::to_string(&tasks).chain_err( || EK::SerializeError, )?; - let mut import = Command::new("task") - .arg("import") - .stdin(Stdio::piped()) - .spawn() - .chain_err(|| EK::TaskCmdError)?; + let mut import = cmd.spawn().chain_err(|| EK::TaskCmdError)?; import .stdin .as_mut() .chain_err(|| EK::TaskCmdError)? .write_all(input_buffer.as_bytes()) .chain_err(|| EK::TaskCmdError)?; - import.wait().chain_err(|| EK::TaskCmdError)?; + Ok(import) +} + +/// This will save the given tasks to taskwarrior. Call with `Some(&task)` if you just have one +/// task. +/// This will block until the save was successful. +pub fn save<'a, T>(tasks: T) -> Result<()> +where + T: IntoIterator<Item = &'a Task>, +{ + save_async(tasks)?.wait().chain_err(|| EK::TaskCmdError)?; Ok(()) } + +/// This function returns the handle to a child process which saves the given tasks. +pub fn save_async<'a, T>(tasks: T) -> Result<Child> +where + T: IntoIterator<Item = &'a Task>, +{ + let mut cmd = Command::new("task"); + cmd.arg("import").stdin(Stdio::piped()); + save_to_cmd(tasks.into_iter().collect(), cmd) +} |