Wip: persistent storage of list entries
This commit is contained in:
parent
78cb4bb1cb
commit
51cba3c68c
@ -7,3 +7,5 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
tui = "0.8.0"
|
tui = "0.8.0"
|
||||||
termion = "1.5"
|
termion = "1.5"
|
||||||
|
serde_json = "1"
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
@ -20,7 +20,7 @@ fn main() -> Result<(), io::Error> {
|
|||||||
let mut inputs = io::stdin().keys();
|
let mut inputs = io::stdin().keys();
|
||||||
let backend = TermionBackend::new(stdout);
|
let backend = TermionBackend::new(stdout);
|
||||||
let mut terminal = Terminal::new(backend)?;
|
let mut terminal = Terminal::new(backend)?;
|
||||||
let mut tracc = Tracc::new();
|
let mut tracc = Tracc::open_or_create();
|
||||||
terminal.hide_cursor()?;
|
terminal.hide_cursor()?;
|
||||||
terminal.clear()?;
|
terminal.clear()?;
|
||||||
loop {
|
loop {
|
||||||
@ -29,7 +29,10 @@ fn main() -> Result<(), io::Error> {
|
|||||||
let input = inputs.next().unwrap().expect("input ded?");
|
let input = inputs.next().unwrap().expect("input ded?");
|
||||||
match tracc.mode {
|
match tracc.mode {
|
||||||
Mode::Normal => match input {
|
Mode::Normal => match input {
|
||||||
Key::Char('q') => break,
|
Key::Char('q') => {
|
||||||
|
tracc.persist();
|
||||||
|
break;
|
||||||
|
},
|
||||||
Key::Char('j') => tracc.selection_down(),
|
Key::Char('j') => tracc.selection_down(),
|
||||||
Key::Char('k') => tracc.selection_up(),
|
Key::Char('k') => tracc.selection_up(),
|
||||||
Key::Char('o') => {
|
Key::Char('o') => {
|
||||||
|
33
src/tracc.rs
33
src/tracc.rs
@ -1,5 +1,8 @@
|
|||||||
use super::Mode;
|
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::backend::Backend;
|
||||||
use tui::Terminal;
|
use tui::Terminal;
|
||||||
|
|
||||||
@ -10,6 +13,7 @@ pub struct Tracc {
|
|||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Todo {
|
pub struct Todo {
|
||||||
text: String,
|
text: String,
|
||||||
done: bool,
|
done: bool,
|
||||||
@ -24,14 +28,19 @@ impl Todo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const JSON_PATH: &str = "tracc.json";
|
||||||
|
|
||||||
|
fn read_todos() -> Option<Vec<Todo>> {
|
||||||
|
File::open(JSON_PATH)
|
||||||
|
.ok()
|
||||||
|
.map(|f| BufReader::new(f))
|
||||||
|
.and_then(|r| from_reader(r).ok())
|
||||||
|
}
|
||||||
|
|
||||||
impl Tracc {
|
impl Tracc {
|
||||||
pub fn new() -> Self {
|
pub fn open_or_create() -> Self {
|
||||||
Self {
|
Self {
|
||||||
todos: vec![
|
todos: read_todos().unwrap_or(vec![Todo::new("This is a list entry")]),
|
||||||
Todo::new("This is a list entry"),
|
|
||||||
Todo::new("a second todo"),
|
|
||||||
Todo::new("And a third"),
|
|
||||||
],
|
|
||||||
selected: Some(0),
|
selected: Some(0),
|
||||||
mode: Mode::Normal,
|
mode: Mode::Normal,
|
||||||
}
|
}
|
||||||
@ -85,7 +94,7 @@ impl Tracc {
|
|||||||
self.remove_current()
|
self.remove_current()
|
||||||
}
|
}
|
||||||
term.hide_cursor()?
|
term.hide_cursor()?
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
self.mode = mode;
|
self.mode = mode;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -98,4 +107,12 @@ impl Tracc {
|
|||||||
pub fn current_pop(&mut self) {
|
pub fn current_pop(&mut self) {
|
||||||
self.todos[self.selected.unwrap()].text.pop();
|
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()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user