2020-04-19 20:11:28 +02:00
use crate ::listview ::ListView ;
2020-01-25 12:11:19 +01:00
use serde ::{ Deserialize , Serialize } ;
use serde_json ::from_reader ;
2020-01-25 18:05:35 +01:00
use std ::fmt ;
2020-04-19 19:22:06 +02:00
use std ::fs ;
use std ::io ;
2020-01-25 12:11:19 +01:00
pub struct TodoList {
pub todos : Vec < Todo > ,
pub selected : usize ,
pub register : Option < Todo > ,
}
#[ derive(Serialize, Deserialize, Default, Clone) ]
pub struct Todo {
text : String ,
done : bool ,
}
impl Todo {
pub fn new ( text : & str ) -> Self {
Todo {
text : text . to_owned ( ) ,
done : false ,
}
}
}
2020-01-25 18:05:35 +01:00
impl fmt ::Display for Todo {
fn fmt ( & self , f : & mut fmt ::Formatter ) -> fmt ::Result {
2020-04-13 23:56:25 +02:00
write! ( f , " [{}] {} " , if self . done { 'x' } else { ' ' } , self . text )
2020-01-25 18:05:35 +01:00
}
}
2020-01-25 12:22:36 +01:00
fn read_todos ( path : & str ) -> Option < Vec < Todo > > {
2020-04-19 19:22:06 +02:00
fs ::File ::open ( path )
2020-01-25 12:11:19 +01:00
. ok ( )
2020-04-19 19:22:06 +02:00
. map ( io ::BufReader ::new )
2020-01-25 12:11:19 +01:00
. and_then ( | r | from_reader ( r ) . ok ( ) )
}
impl TodoList {
2020-01-25 12:22:36 +01:00
pub fn open_or_create ( path : & str ) -> Self {
2020-04-13 23:56:25 +02:00
Self {
2020-04-19 19:22:06 +02:00
todos : read_todos ( path ) . unwrap_or_else ( | | vec! [ Todo ::new ( " This is a list entry " ) ] ) ,
2020-01-25 12:11:19 +01:00
selected : 0 ,
register : None ,
}
}
2020-04-27 12:34:58 +02:00
pub fn toggle_current ( & mut self ) {
self . todos [ self . selected ] . done = ! self . todos [ self . selected ] . done ;
2020-05-27 11:42:17 +02:00
self . selected = ( self . selected + 1 ) . min ( self . todos . len ( ) - 1 )
2020-04-27 12:34:58 +02:00
}
2020-01-27 12:06:05 +01:00
fn current ( & self ) -> & Todo {
& self . todos [ self . selected ]
}
}
impl ListView < Todo > for TodoList {
2020-04-13 23:56:25 +02:00
fn selection_pointer ( & mut self ) -> & mut usize {
& mut self . selected
2020-01-25 12:11:19 +01:00
}
2020-04-13 23:56:25 +02:00
fn list ( & mut self ) -> & mut Vec < Todo > {
& mut self . todos
2020-01-25 12:11:19 +01:00
}
2020-04-13 23:56:25 +02:00
fn register ( & mut self ) -> & mut Option < Todo > {
& mut self . register
2020-01-25 12:11:19 +01:00
}
2020-01-27 12:06:05 +01:00
fn normal_mode ( & mut self ) {
2020-01-25 12:11:19 +01:00
if self . current ( ) . text . is_empty ( ) {
self . remove_current ( ) ;
self . selected = self . selected . saturating_sub ( 1 ) ;
}
}
2020-01-27 12:06:05 +01:00
fn append_to_current ( & mut self , chr : char ) {
2020-01-25 12:11:19 +01:00
self . todos [ self . selected ] . text . push ( chr ) ;
}
2020-01-27 12:06:05 +01:00
fn backspace ( & mut self ) {
2020-01-25 12:11:19 +01:00
self . todos [ self . selected ] . text . pop ( ) ;
}
}