Slightly refactor json read/write

This commit is contained in:
kageru 2020-01-25 12:22:36 +01:00
parent 904a3dbe2d
commit 54c217741c
Signed by untrusted user: kageru
GPG Key ID: 8282A2BEA4ADA3D2
2 changed files with 23 additions and 26 deletions

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::from_reader; use serde_json::from_reader;
use std::fs::File; use std::fs::File;
use std::io::{BufReader, Write}; use std::io::BufReader;
pub struct TodoList { pub struct TodoList {
// We use owned strings here because they’re easier to manipulate when editing. // We use owned strings here because they’re easier to manipulate when editing.
@ -25,19 +25,17 @@ impl Todo {
} }
} }
const JSON_PATH: &str = "tracc.json"; fn read_todos(path: &str) -> Option<Vec<Todo>> {
File::open(path)
fn read_todos() -> Option<Vec<Todo>> {
File::open(JSON_PATH)
.ok() .ok()
.map(|f| BufReader::new(f)) .map(|f| BufReader::new(f))
.and_then(|r| from_reader(r).ok()) .and_then(|r| from_reader(r).ok())
} }
impl TodoList { impl TodoList {
pub fn open_or_create() -> Self { pub fn open_or_create(path: &str) -> Self {
TodoList { TodoList {
todos: read_todos().unwrap_or(vec![Todo::new("This is a list entry")]), todos: read_todos(path).unwrap_or(vec![Todo::new("This is a list entry")]),
selected: 0, selected: 0,
register: None, register: None,
} }
@ -99,16 +97,4 @@ impl TodoList {
pub fn current_pop(&mut self) { pub fn current_pop(&mut self) {
self.todos[self.selected].text.pop(); self.todos[self.selected].text.pop();
} }
pub fn persist(&self) {
let string = serde_json::to_string(&self.todos).unwrap();
std::fs::OpenOptions::new()
.create(true)
.write(true)
.truncate(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()));
}
} }

View File

@ -1,6 +1,6 @@
use super::todolist::TodoList; use super::todolist::TodoList;
use std::default::Default; use std::default::Default;
use std::io; use std::io::{self,Write};
use termion::event::Key; use termion::event::Key;
use termion::input::TermRead; use termion::input::TermRead;
use tui::backend::TermionBackend; use tui::backend::TermionBackend;
@ -8,6 +8,7 @@ use tui::style::{Color, Style};
use tui::widgets::*; use tui::widgets::*;
type Terminal = tui::Terminal<TermionBackend<termion::raw::RawTerminal<io::Stdout>>>; type Terminal = tui::Terminal<TermionBackend<termion::raw::RawTerminal<io::Stdout>>>;
const JSON_PATH: &str = "tracc.json";
pub enum Mode { pub enum Mode {
Insert, Insert,
@ -23,7 +24,7 @@ pub struct Tracc {
impl Tracc { impl Tracc {
pub fn new(terminal: Terminal) -> Self { pub fn new(terminal: Terminal) -> Self {
Self { Self {
todos: TodoList::open_or_create(), todos: TodoList::open_or_create(JSON_PATH),
terminal, terminal,
input_mode: Mode::Normal, input_mode: Mode::Normal,
} }
@ -37,11 +38,7 @@ impl Tracc {
let input = inputs.next().unwrap()?; let input = inputs.next().unwrap()?;
match self.input_mode { match self.input_mode {
Mode::Normal => match input { Mode::Normal => match input {
Key::Char('q') => { Key::Char('q') => break,
self.todos.persist();
self.terminal.clear()?;
break;
}
Key::Char('j') => self.todos.selection_down(), Key::Char('j') => self.todos.selection_down(),
Key::Char('k') => self.todos.selection_up(), Key::Char('k') => self.todos.selection_up(),
Key::Char('o') => { Key::Char('o') => {
@ -71,6 +68,8 @@ impl Tracc {
}, },
}; };
} }
self.terminal.clear()?;
persist_todos(&self.todos, JSON_PATH);
Ok(()) Ok(())
} }
@ -101,3 +100,15 @@ fn refresh(terminal: &mut Terminal, todos: &TodoList) -> Result<(), io::Error> {
})?; })?;
Ok(()) Ok(())
} }
fn persist_todos(todos: &TodoList, path: &str) {
let string = serde_json::to_string(&todos.todos).unwrap();
std::fs::OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(path)
.ok()
.or_else(|| panic!("Can’t save todos to JSON. Dumping raw data:\n{}", string))
.map(|mut f| f.write(string.as_bytes()));
}