diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-12-18 11:13:13 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-18 11:13:13 +0000 |
commit | fe166cc387f1dfed72818191e703bfb8c33effe8 (patch) | |
tree | ed01c84960333e43e1f42566db60f79065a97122 | |
parent | fe836ce049352315a983fffded9bc7f15040af1b (diff) | |
parent | 224bdf5b20c9592529a40a01f6721def039fbf7c (diff) |
Merge #22
22: Replace failure with thiserror r=matthiasbeyer a=matthiasbeyer
Co-authored-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/error.rs | 20 | ||||
-rw-r--r-- | src/import.rs | 21 | ||||
-rw-r--r-- | src/tw.rs | 31 |
4 files changed, 36 insertions, 38 deletions
@@ -26,7 +26,7 @@ serde_json = "1" uuid = { version = "1.2", features = ["serde", "v4"] } log = "0.4" derive_builder = "0.12.0" -failure = "0.1" +thiserror = "1" [dev-dependencies] env_logger = "0.10" diff --git a/src/error.rs b/src/error.rs index 6469c26..7c4a4b6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -7,21 +7,29 @@ //! Definitions for error handling with failure /// Failure error kind type, defining error messages -#[derive(Debug, Clone, Eq, PartialEq, failure::Fail)] -pub enum ErrorKind { +#[derive(Debug, thiserror::Error)] +pub enum Error { /// Error kind indicating that the JSON parser failed - #[fail(display = "Failed to create a Task from JSON")] + #[error("Failed to create a Task from JSON")] ParserError, /// Error kind indicating that the Reader failed to read something - #[fail(display = "Failed to read tasks from a Reader")] + #[error("Failed to read tasks from a Reader")] ReaderError, /// Error kind indicating that a call to the task warrior binary failed - #[fail(display = "There was a problem while calling the external 'task' binary")] + #[error("There was a problem while calling the external 'task' binary")] TaskCmdError, /// Error kind indicating that a conversion to JSON failed - #[fail(display = "A Task could not be converted to JSON")] + #[error("A Task could not be converted to JSON")] SerializeError, + + /// Error wrapper for std::io::Error + #[error(transparent)] + Io(#[from] std::io::Error), + + /// Error wrapper for serde_json::Error + #[error(transparent)] + SerdeJson(#[from] serde_json::Error), } diff --git a/src/import.rs b/src/import.rs index 19acd0e..a82d172 100644 --- a/src/import.rs +++ b/src/import.rs @@ -9,35 +9,28 @@ use std::io::BufRead; use std::io::Read; -use failure::Error; -use failure::Fallible as Result; -use failure::ResultExt; use serde_json; -use crate::error::ErrorKind as EK; +use crate::error::Error; use crate::task::Task; /// Import taskwarrior-exported JSON. This expects an JSON Array of objects, as exported by /// taskwarrior. -pub fn import<R: Read>(r: R) -> Result<Vec<Task>> { - serde_json::from_reader(r) - .context(EK::ParserError) - .map_err(Error::from) +pub fn import<R: Read>(r: R) -> Result<Vec<Task>, Error> { + serde_json::from_reader(r).map_err(Error::from) } /// Import a single JSON-formatted Task -pub fn import_task(s: &str) -> Result<Task> { - serde_json::from_str(s) - .context(EK::ParserError) - .map_err(Error::from) +pub fn import_task(s: &str) -> Result<Task, Error> { + serde_json::from_str(s).map_err(Error::from) } /// Reads line by line and tries to parse a task-object per line. -pub fn import_tasks<BR: BufRead>(r: BR) -> Vec<Result<Task>> { +pub fn import_tasks<BR: BufRead>(r: BR) -> Vec<Result<Task, Error>> { let mut vt = Vec::new(); for line in r.lines() { if let Err(err) = line { - vt.push(Err(err).context(EK::ReaderError).map_err(Error::from)); + vt.push(Err(Error::from(err))); continue; } // Unwrap is safe because of continue above @@ -8,20 +8,18 @@ //! in your path. This will always call task and never interact with your `.task` directory itself. //! (This is in accordance with the taskwarrior api guide lines.) -use crate::error::ErrorKind as EK; +use crate::error::Error; use crate::import::import; use crate::task::Task; use std::io::Write; use std::iter::once; use std::process::{Child, Command, Stdio}; -use failure::Fallible as Result; -use failure::ResultExt; 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>> { +pub fn query(query: &str) -> Result<Vec<Task>, Error> { let mut cmd = add_query_to_cmd(query, Command::new("task")); cmd.stdout(Stdio::piped()); run_query_cmd(cmd) @@ -37,38 +35,37 @@ pub fn add_query_to_cmd(query: &str, mut cmd: Command) -> Command { } /// 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().context(EK::TaskCmdError)?; - export.wait().context(EK::TaskCmdError)?; - import(export.stdout.ok_or(EK::TaskCmdError)?) +pub fn run_query_cmd(mut cmd: Command) -> Result<Vec<Task>, Error> { + let mut export = cmd.spawn()?; + export.wait()?; + import(export.stdout.ok_or(Error::TaskCmdError)?) } /// 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(tasks: Vec<&'_ Task>, mut cmd: Command) -> Result<Child> { - let input_buffer = serde_json::to_string(&tasks).context(EK::SerializeError)?; - let mut import = cmd.spawn().context(EK::TaskCmdError)?; +pub fn save_to_cmd(tasks: Vec<&'_ Task>, mut cmd: Command) -> Result<Child, Error> { + let input_buffer = serde_json::to_string(&tasks)?; + let mut import = cmd.spawn()?; import .stdin .as_mut() - .ok_or(EK::TaskCmdError)? - .write_all(input_buffer.as_bytes()) - .context(EK::TaskCmdError)?; + .ok_or(Error::TaskCmdError)? + .write_all(input_buffer.as_bytes())?; 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<()> +pub fn save<'a, T>(tasks: T) -> Result<(), Error> where T: IntoIterator<Item = &'a Task>, { - save_async(tasks)?.wait().context(EK::TaskCmdError)?; + save_async(tasks)?.wait()?; 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> +pub fn save_async<'a, T>(tasks: T) -> Result<Child, Error> where T: IntoIterator<Item = &'a Task>, { |