diff --git a/Cargo.lock b/Cargo.lock index 04516a1..0501f5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,6 +90,7 @@ dependencies = [ "libc", "num-integer", "num-traits", + "serde", "time", "winapi", ] @@ -487,6 +488,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_yaml" version = "0.8.17" @@ -597,6 +609,7 @@ dependencies = [ "regex", "rusqlite", "serde", + "serde_json", "serde_yaml", "tempfile", "textwrap 0.14.2", diff --git a/Cargo.toml b/Cargo.toml index c7191ed..57cdb67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ path = "src/main.rs" [dependencies] clap = "2" -chrono = "0.4" +chrono = { version = "0.4", features = ["serde"] } rusqlite = { version = "0.25.3", features = ["chrono"] } thiserror = "*" directories = "*" @@ -26,6 +26,7 @@ csv = "1.1" regex = "1.5" lazy_static = "1.4" tempfile = "3" +serde_json = "1.0" [dev-dependencies] pretty_assertions = "0.7.2" diff --git a/src/error.rs b/src/error.rs index 2fbc8bc..0587805 100644 --- a/src/error.rs +++ b/src/error.rs @@ -69,6 +69,11 @@ some human times, for now restricted to time ago: #[error("CSV Error: {0}")] CSVError(#[from] csv::Error), + #[error("Could not serialize to json. + +{0}")] + SerdeJsonError(#[from] serde_json::Error), + #[error("Corrupted data found in the database: {0} diff --git a/src/formatters.rs b/src/formatters.rs index f088d72..cc95377 100644 --- a/src/formatters.rs +++ b/src/formatters.rs @@ -9,12 +9,14 @@ use crate::models::Entry; pub mod text; pub mod csv; +pub mod json; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum Formatter { Text, Csv, + Json, Custom(String), } @@ -35,6 +37,7 @@ impl Formatter { match &self { Formatter::Text => text::print_formatted(entries, out, now, ids)?, Formatter::Csv => csv::print_formatted(entries, out, ids)?, + Formatter::Json => json::print_formatted(entries, out)?, Formatter::Custom(name) => { panic!("attempted custom formatter with name {} which is not implemented", name); } @@ -53,6 +56,7 @@ impl FromStr for Formatter { Ok(match &*lower { "text" => Formatter::Text, "csv" => Formatter::Csv, + "json" => Formatter::Json, custom_format => Formatter::Custom(custom_format.into()), }) } diff --git a/src/formatters/json.rs b/src/formatters/json.rs new file mode 100644 index 0000000..bc2d55e --- /dev/null +++ b/src/formatters/json.rs @@ -0,0 +1,8 @@ +use std::io::Write; + +use crate::models::Entry; +use crate::error::Result; + +pub fn print_formatted(entries: Vec, out: &mut W) -> Result<()> { + Ok(serde_json::to_writer(out, &entries)?) +} diff --git a/src/models.rs b/src/models.rs index 6d1687b..00afacc 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,6 +1,7 @@ use chrono::{DateTime, Utc}; +use serde::Serialize; -#[derive(Debug)] +#[derive(Debug, Serialize)] pub struct Entry { pub id: u64, pub note: Option,