diff --git a/Cargo.lock b/Cargo.lock index 68662de..48398d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,6 +90,7 @@ dependencies = [ "libc", "mio", "parking_lot", + "serde", "signal-hook", "signal-hook-mio", "winapi", @@ -206,6 +207,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + [[package]] name = "lazy_static" version = "1.4.0" @@ -435,6 +442,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + [[package]] name = "same-file" version = "1.0.6" @@ -470,6 +483,17 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_spanned" version = "0.6.3" @@ -651,6 +675,7 @@ dependencies = [ "ratatui", "rust-embed", "serde", + "serde_json", "structopt", "toml", ] diff --git a/Cargo.toml b/Cargo.toml index dd1596e..931b75c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,13 @@ edition = "2021" [dependencies] structopt = "^0.3" dirs = "^5.0" -crossterm = "^0.26" rust-embed = "^6.4" toml = "^0.7" +serde_json = "1.0" + +[dependencies.crossterm] +version = "^0.26" +features = ["serde"] [dependencies.ratatui] version = "^0.21" diff --git a/src/main.rs b/src/main.rs index bc5a3e5..8be85c6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,8 @@ use crossterm::{ use rand::{seq::SliceRandom, thread_rng}; use ratatui::{backend::CrosstermBackend, terminal::Terminal}; use rust_embed::RustEmbed; +use serde::Serialize; +use serde_json; use std::{ ffi::OsString, fs, @@ -261,6 +263,8 @@ fn main() -> crossterm::Result<()> { if let Event::Key(key) = event { test.handle_key(key); if test.complete { + let data = serde_json::to_string(&test.words).unwrap(); + fs::write("export.json", data).expect("Unable to write file"); state = State::Results(Results::from(&*test)); } } diff --git a/src/test/mod.rs b/src/test/mod.rs index 01295d9..db99fb4 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -1,10 +1,24 @@ pub mod results; use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; +use serde::{Serialize, Serializer}; use std::fmt; use std::time::Instant; +pub fn serialize_instant(instant: &Instant, serializer: S) -> Result +where + S: Serializer, +{ + let duration = instant.elapsed(); + duration.serialize(serializer) +} + +#[derive(Clone, Serialize)] pub struct TestEvent { + #[serde( + serialize_with = "serialize_instant", + deserialize_with = "deserialize_instant" + )] pub time: Instant, pub key: KeyEvent, pub correct: Option, @@ -19,7 +33,7 @@ impl fmt::Debug for TestEvent { } } -#[derive(Debug)] +#[derive(Clone, Debug, Serialize)] pub struct TestWord { pub text: String, pub progress: String,