Remove empty logs

This commit is contained in:
Joscha 2022-01-08 04:11:55 +01:00
parent 26c9c1faf1
commit efc97800b2
2 changed files with 41 additions and 14 deletions

View file

@ -28,6 +28,11 @@ struct LoadedFile {
file: File, file: File,
/// Whether this file has been changed. /// Whether this file has been changed.
dirty: bool, dirty: bool,
/// Commands that have been removed and are to be skipped during formatting.
///
/// They are not directly removed from the list of commands in order not to
/// change other commands' indices.
removed: HashSet<usize>,
} }
impl LoadedFile { impl LoadedFile {
@ -37,6 +42,7 @@ impl LoadedFile {
cs_id, cs_id,
file, file,
dirty: false, dirty: false,
removed: HashSet::new(),
} }
} }
} }
@ -292,7 +298,7 @@ impl Files {
fn save_file(file: &LoadedFile) -> Result<()> { fn save_file(file: &LoadedFile) -> Result<()> {
// TODO Sort commands within file // TODO Sort commands within file
let formatted = format!("{}", file.file); let formatted = file.file.format(&file.removed);
if file.file.contents == formatted { if file.file.contents == formatted {
println!("Unchanged file {:?}", file.name); println!("Unchanged file {:?}", file.name);
} else { } else {
@ -382,6 +388,12 @@ impl Files {
file.dirty = true; file.dirty = true;
} }
fn remove(&mut self, source: Source) {
let file = &mut self.files[source.file];
file.removed.insert(source.command);
file.dirty = true;
}
/// Add a [`Done`] statement to the task identified by `source`. /// Add a [`Done`] statement to the task identified by `source`.
/// ///
/// Returns whether the addition was successful. It can fail if the entry /// Returns whether the addition was successful. It can fail if the entry
@ -399,11 +411,15 @@ impl Files {
pub fn set_log(&mut self, date: NaiveDate, desc: Vec<String>) { pub fn set_log(&mut self, date: NaiveDate, desc: Vec<String>) {
if let Some(source) = self.logs.get(&date).cloned() { if let Some(source) = self.logs.get(&date).cloned() {
if desc.is_empty() {
self.remove(source);
} else {
self.modify(source, |command| match command { self.modify(source, |command| match command {
Command::Log(log) => log.desc = desc, Command::Log(log) => log.desc = desc,
_ => unreachable!(), _ => unreachable!(),
}); });
} else { }
} else if !desc.is_empty() {
let file = self let file = self
.latest_log_before(date) .latest_log_before(date)
.or_else(|| self.latest_log()) .or_else(|| self.latest_log())

View file

@ -1,3 +1,4 @@
use std::collections::HashSet;
use std::fmt; use std::fmt;
use chrono::Datelike; use chrono::Datelike;
@ -317,21 +318,31 @@ impl fmt::Display for Log {
} }
} }
impl fmt::Display for File { impl File {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub fn format(&self, removed: &HashSet<usize>) -> String {
for i in 0..self.commands.len() { let mut result = String::new();
let curr = &self.commands[i];
let next = self.commands.get(i + 1);
write!(f, "{}", curr)?; let commands = self
.commands
.iter()
.enumerate()
.filter(|(i, _)| !removed.contains(i))
.map(|(_, c)| c)
.collect::<Vec<_>>();
for i in 0..commands.len() {
let curr = commands[i];
let next = commands.get(i + 1).copied();
result.push_str(&format!("{}", curr));
match (curr, next) { match (curr, next) {
(Command::Include(_), Some(Command::Include(_))) => {} (Command::Include(_), Some(Command::Include(_))) => {}
(_, None) => {} (_, None) => {}
_ => writeln!(f)?, _ => result.push('\n'),
} }
} }
Ok(()) result
} }
} }