From d27812b836816a79e286567560b401cd7b2f9b96 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 2 Jan 2022 00:42:06 +0100 Subject: [PATCH] Represent commands in file uniformly --- src/files/commands.rs | 29 +++-------------------------- src/files/format.rs | 35 +++++++++++------------------------ src/files/parse.rs | 34 +++++++++++----------------------- 3 files changed, 25 insertions(+), 73 deletions(-) diff --git a/src/files/commands.rs b/src/files/commands.rs index ebb93d0..b527d99 100644 --- a/src/files/commands.rs +++ b/src/files/commands.rs @@ -345,38 +345,15 @@ pub struct Log { #[derive(Debug)] pub enum Command { + Include(String), + Timezone(String), Task(Task), Note(Note), -} - -impl Command { - pub fn title(&self) -> &str { - match self { - Self::Task(task) => &task.title, - Self::Note(note) => ¬e.title, - } - } - - pub fn desc(&self) -> &[String] { - match self { - Self::Task(task) => &task.desc, - Self::Note(note) => ¬e.desc, - } - } - - pub fn statements(&self) -> &[Statement] { - match self { - Self::Task(task) => &task.statements, - Self::Note(note) => ¬e.statements, - } - } + Log(Log), } #[derive(Debug)] pub struct File { pub contents: String, - pub includes: Vec, - pub timezone: Option, - pub logs: Vec, pub commands: Vec, } diff --git a/src/files/format.rs b/src/files/format.rs index bc46e19..4274a2a 100644 --- a/src/files/format.rs +++ b/src/files/format.rs @@ -300,8 +300,11 @@ impl fmt::Display for Note { impl fmt::Display for Command { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { + Command::Include(name) => writeln!(f, "INCLUDE {}", name), + Command::Timezone(name) => writeln!(f, "TIMEZONE {}", name), Command::Task(task) => write!(f, "{}", task), Command::Note(note) => write!(f, "{}", note), + Command::Log(log) => write!(f, "{}", log), } } } @@ -316,33 +319,17 @@ impl fmt::Display for Log { impl fmt::Display for File { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut empty = true; + for i in 0..self.commands.len() { + let curr = &self.commands[i]; + let next = self.commands.get(i + 1); - // TODO Sort includes alphabetically - for include in &self.includes { - writeln!(f, "INCLUDE {}", include)?; - empty = false; - } + write!(f, "{}", curr)?; - if let Some(tz) = &self.timezone { - if !empty { - writeln!(f)?; + match (curr, next) { + (Command::Include(_), Some(Command::Include(_))) => {} + (_, None) => {} + _ => writeln!(f)?, } - writeln!(f, "TIMEZONE {}", tz)?; - empty = false; - } - - // TODO Sort logs from old to new - for log in &self.logs { - writeln!(f, "{}", log)?; - } - - for command in &self.commands { - if !empty { - writeln!(f)?; - } - write!(f, "{}", command)?; - empty = false; } Ok(()) diff --git a/src/files/parse.rs b/src/files/parse.rs index a60c850..2f5f615 100644 --- a/src/files/parse.rs +++ b/src/files/parse.rs @@ -812,46 +812,34 @@ fn parse_log(p: Pair<'_, Rule>) -> Result { Ok(Log { date, desc }) } -fn parse_command(p: Pair<'_, Rule>, file: &mut File) -> Result<()> { +fn parse_command(p: Pair<'_, Rule>) -> Result { assert_eq!(p.as_rule(), Rule::command); let p = p.into_inner().next().unwrap(); - match p.as_rule() { - Rule::include => file.includes.push(parse_include(p)), - Rule::timezone => match file.timezone { - None => file.timezone = Some(parse_timezone(p)), - Some(_) => fail(p.as_span(), "cannot set timezone multiple times")?, - }, - Rule::task => file.commands.push(Command::Task(parse_task(p)?)), - Rule::note => file.commands.push(Command::Note(parse_note(p)?)), - Rule::log => file.logs.push(parse_log(p)?), + Ok(match p.as_rule() { + Rule::include => Command::Include(parse_include(p)), + Rule::timezone => Command::Timezone(parse_timezone(p)), + Rule::task => Command::Task(parse_task(p)?), + Rule::note => Command::Note(parse_note(p)?), + Rule::log => Command::Log(parse_log(p)?), _ => unreachable!(), - } - - Ok(()) + }) } pub fn parse_file(p: Pair<'_, Rule>, contents: String) -> Result { assert_eq!(p.as_rule(), Rule::file); - let mut file = File { - contents, - includes: vec![], - timezone: None, - logs: vec![], - commands: vec![], - }; - + let mut commands = vec![]; for p in p.into_inner() { // For some reason, the EOI in `file` always gets captured if p.as_rule() == Rule::EOI { break; } - parse_command(p, &mut file)?; + commands.push(parse_command(p)?); } - Ok(file) + Ok(File { contents, commands }) } pub fn parse(path: &Path, input: &str) -> Result {