From 51cba3c68c69652dc09bde21c673f985cd7db51c Mon Sep 17 00:00:00 2001 From: kageru Date: Fri, 24 Jan 2020 00:02:32 +0100 Subject: [PATCH] Wip: persistent storage of list entries --- Cargo.toml | 2 ++ src/main.rs | 7 +++++-- src/tracc.rs | 35 ++++++++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e9b5503..78a91d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,5 @@ edition = "2018" [dependencies] tui = "0.8.0" termion = "1.5" +serde_json = "1" +serde = { version = "1", features = ["derive"] } diff --git a/src/main.rs b/src/main.rs index b520d94..48111e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,7 @@ fn main() -> Result<(), io::Error> { let mut inputs = io::stdin().keys(); let backend = TermionBackend::new(stdout); let mut terminal = Terminal::new(backend)?; - let mut tracc = Tracc::new(); + let mut tracc = Tracc::open_or_create(); terminal.hide_cursor()?; terminal.clear()?; loop { @@ -29,7 +29,10 @@ fn main() -> Result<(), io::Error> { let input = inputs.next().unwrap().expect("input ded?"); match tracc.mode { Mode::Normal => match input { - Key::Char('q') => break, + Key::Char('q') => { + tracc.persist(); + break; + }, Key::Char('j') => tracc.selection_down(), Key::Char('k') => tracc.selection_up(), Key::Char('o') => { diff --git a/src/tracc.rs b/src/tracc.rs index d5b7018..4db36c7 100644 --- a/src/tracc.rs +++ b/src/tracc.rs @@ -1,5 +1,8 @@ use super::Mode; -use std::io; +use serde::{Deserialize, Serialize}; +use serde_json::from_reader; +use std::fs::File; +use std::io::{self, BufReader, Write}; use tui::backend::Backend; use tui::Terminal; @@ -10,6 +13,7 @@ pub struct Tracc { pub mode: Mode, } +#[derive(Serialize, Deserialize)] pub struct Todo { text: String, done: bool, @@ -24,14 +28,19 @@ impl Todo { } } +const JSON_PATH: &str = "tracc.json"; + +fn read_todos() -> Option> { + File::open(JSON_PATH) + .ok() + .map(|f| BufReader::new(f)) + .and_then(|r| from_reader(r).ok()) +} + impl Tracc { - pub fn new() -> Self { + pub fn open_or_create() -> Self { Self { - todos: vec![ - Todo::new("This is a list entry"), - Todo::new("a second todo"), - Todo::new("And a third"), - ], + todos: read_todos().unwrap_or(vec![Todo::new("This is a list entry")]), selected: Some(0), mode: Mode::Normal, } @@ -84,8 +93,8 @@ impl Tracc { if self.current().text.is_empty() { self.remove_current() } - term.hide_cursor()? - }, + term.hide_cursor()? + } }; self.mode = mode; Ok(()) @@ -98,4 +107,12 @@ impl Tracc { pub fn current_pop(&mut self) { self.todos[self.selected.unwrap()].text.pop(); } + + pub fn persist(self) { + let string = serde_json::to_string(&self.todos).unwrap(); + std::fs::OpenOptions::new().create(true).write(true).open(JSON_PATH) + .ok() + .or_else(|| panic!("Can’t save todos to JSON. Dumping raw data:\n{}", string)) + .map(|mut f| f.write(string.as_bytes())); + } }