This commit is contained in:
kageru 2020-04-19 19:22:06 +02:00
parent 1be551d4f5
commit 1204be40fb
Signed by: kageru
GPG Key ID: 8282A2BEA4ADA3D2
3 changed files with 23 additions and 28 deletions

View File

@ -2,11 +2,12 @@ use super::tracc::ListView;
use itertools::Itertools; use itertools::Itertools;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::from_reader; use serde_json::from_reader;
use std::collections;
use std::default; use std::default;
use std::fmt; use std::fmt;
use std::fs::File; use std::fs;
use std::io::BufReader; use std::io;
use time::OffsetDateTime; use time::{Duration, OffsetDateTime};
pub struct TimeSheet { pub struct TimeSheet {
pub times: Vec<TimePoint>, pub times: Vec<TimePoint>,
@ -50,16 +51,16 @@ impl default::Default for TimePoint {
} }
fn read_times(path: &str) -> Option<Vec<TimePoint>> { fn read_times(path: &str) -> Option<Vec<TimePoint>> {
File::open(path) fs::File::open(path)
.ok() .ok()
.map(|f| BufReader::new(f)) .map(io::BufReader::new)
.and_then(|r| from_reader(r).ok()) .and_then(|r| from_reader(r).ok())
} }
impl TimeSheet { impl TimeSheet {
pub fn open_or_create(path: &str) -> Self { pub fn open_or_create(path: &str) -> Self {
Self { Self {
times: read_times(path).unwrap_or(vec![TimePoint::new("Did something")]), times: read_times(path).unwrap_or_else(|| vec![TimePoint::new("Did something")]),
selected: 0, selected: 0,
register: None, register: None,
editing_time: false, editing_time: false,
@ -79,13 +80,10 @@ impl TimeSheet {
.iter() .iter()
.tuple_windows() .tuple_windows()
.map(|(prev, next)| (prev.text.clone(), next.time - prev.time)) .map(|(prev, next)| (prev.text.clone(), next.time - prev.time))
.fold( .fold(collections::BTreeMap::new(), |mut map, (text, duration)| {
std::collections::BTreeMap::new(), *map.entry(text).or_insert_with(Duration::zero) += duration;
|mut map, (text, duration)| { map
*map.entry(text).or_insert(time::Duration::zero()) += duration; })
map
},
)
.into_iter() .into_iter()
.map(|(text, duration)| format!("{}: {}", text, format_duration(&duration))) .map(|(text, duration)| format!("{}: {}", text, format_duration(&duration)))
.join(" | ") .join(" | ")
@ -97,14 +95,14 @@ impl TimeSheet {
.iter() .iter()
.map(|tp| tp.time) .map(|tp| tp.time)
.tuple_windows() .tuple_windows()
.fold(time::Duration::zero(), |total, (last, next)| { .fold(Duration::zero(), |total, (last, next)| {
total + (next - last) total + (next - last)
}); });
format_duration(&total) format_duration(&total)
} }
} }
fn format_duration(d: &time::Duration) -> String { fn format_duration(d: &Duration) -> String {
format!("{}:{:02}", d.whole_hours(), d.whole_minutes().max(1) % 60) format!("{}:{:02}", d.whole_hours(), d.whole_minutes().max(1) % 60)
} }

View File

@ -2,8 +2,8 @@ use crate::tracc::ListView;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::from_reader; use serde_json::from_reader;
use std::fmt; use std::fmt;
use std::fs::File; use std::fs;
use std::io::BufReader; use std::io;
pub struct TodoList { pub struct TodoList {
pub todos: Vec<Todo>, pub todos: Vec<Todo>,
@ -13,7 +13,6 @@ pub struct TodoList {
#[derive(Serialize, Deserialize, Default, Clone)] #[derive(Serialize, Deserialize, Default, Clone)]
pub struct Todo { pub struct Todo {
// We use owned strings here because they’re easier to manipulate when editing.
text: String, text: String,
done: bool, done: bool,
} }
@ -34,16 +33,16 @@ impl fmt::Display for Todo {
} }
fn read_todos(path: &str) -> Option<Vec<Todo>> { fn read_todos(path: &str) -> Option<Vec<Todo>> {
File::open(path) fs::File::open(path)
.ok() .ok()
.map(|f| BufReader::new(f)) .map(io::BufReader::new)
.and_then(|r| from_reader(r).ok()) .and_then(|r| from_reader(r).ok())
} }
impl TodoList { impl TodoList {
pub fn open_or_create(path: &str) -> Self { pub fn open_or_create(path: &str) -> Self {
Self { Self {
todos: read_todos(path).unwrap_or(vec![Todo::new("This is a list entry")]), todos: read_todos(path).unwrap_or_else(|| vec![Todo::new("This is a list entry")]),
selected: 0, selected: 0,
register: None, register: None,
} }

View File

@ -99,7 +99,7 @@ impl Tracc {
Mode::Normal => { Mode::Normal => {
self.todos.normal_mode(); self.todos.normal_mode();
self.times.normal_mode(); self.times.normal_mode();
self.terminal.hide_cursor()? self.terminal.hide_cursor()?;
} }
}; };
self.input_mode = mode; self.input_mode = mode;
@ -119,7 +119,7 @@ impl Tracc {
.borders(Borders::TOP | Borders::RIGHT | Borders::LEFT), .borders(Borders::TOP | Borders::RIGHT | Borders::LEFT),
) )
.items(content) .items(content)
.select(selected.into()) .select(selected)
.highlight_style(Style::default().fg(Color::LightGreen)) .highlight_style(Style::default().fg(Color::LightGreen))
.highlight_symbol(">") .highlight_symbol(">")
} }
@ -150,7 +150,7 @@ impl Tracc {
Paragraph::new( Paragraph::new(
[ [
Text::raw(format!("Sum for today: {}\n", total_time)), Text::raw(format!("Sum for today: {}\n", total_time)),
Text::raw(times) Text::raw(times),
] ]
.iter(), .iter(),
) )
@ -223,10 +223,8 @@ pub trait ListView<T: fmt::Display + Clone> {
} }
fn paste(&mut self) { fn paste(&mut self) {
let register = self.register().clone(); if let Some(item) = self.register().clone() {
match register { self.insert(item, None);
Some(item) => self.insert(item, None),
None => (),
} }
} }