summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2022-12-18 11:57:43 +0100
committerMatthias Beyer <mail@beyermatthias.de>2022-12-18 12:12:07 +0100
commit224bdf5b20c9592529a40a01f6721def039fbf7c (patch)
treeed01c84960333e43e1f42566db60f79065a97122
parentfe836ce049352315a983fffded9bc7f15040af1b (diff)
Replace failure with thiserror
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--Cargo.toml2
-rw-r--r--src/error.rs20
-rw-r--r--src/import.rs21
-rw-r--r--src/tw.rs31
4 files changed, 36 insertions, 38 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 0888d1d..20ae50f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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
diff --git a/src/tw.rs b/src/tw.rs
index 0a4f1d9..7b31993 100644
--- a/src/tw.rs
+++ b/src/tw.rs
@@ -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>,
{