use std::str::FromStr; use std::io::Write; use serde::{Serialize, Deserialize}; use crate::error; use crate::models::Entry; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum Formatter { Text, Custom(String), } impl Formatter { pub fn print_formatted(&self, entries: Vec, out: &mut W) -> error::Result<()> { match &self { Formatter::Text => { for entry in entries { writeln!(out, "{:?}", entry)?; } } Formatter::Custom(name) => { } } Ok(()) } } impl FromStr for Formatter { type Err = error::Error; fn from_str(s: &str) -> error::Result { let lower = s.to_lowercase(); Ok(match &*lower { "text" => Formatter::Text, custom_format => Formatter::Custom(custom_format.into()), }) } } #[cfg(test)] mod tests { use super::*; use crate::types::Time; #[test] fn test_text_output() { let formatter = Formatter::Text; let mut output = Vec::new(); let entries = vec![ Entry::new_sample(1, Time::new(2008, 10, 3, 12, 0, 0), Some(Time::new(2008, 10, 3, 14, 0, 0))), Entry::new_sample(2, Time::new(2008, 10, 3, 12, 0, 0), Some(Time::new(2008, 10, 3, 14, 0, 0))), Entry::new_sample(3, Time::new(2008, 10, 5, 16, 0, 0), Some(Time::new(2008, 10, 3, 18, 0, 0))), Entry::new_sample(4, Time::new(2008, 10, 5, 18, 0, 0), None), ]; formatter.print_formatted(entries, &mut output).unwrap(); assert_eq!(String::from_utf8_lossy(&output), "Timesheet: SpecSheet Day Start End Duration Notes Fri Oct 03, 2008 12:00:00 - 14:00:00 2:00:00 entry 1 16:00:00 - 18:00:00 2:00:00 entry 2 4:00:00 Sun Oct 05, 2008 16:00:00 - 18:00:00 2:00:00 entry 3 18:00:00 - 2:00:00 entry 4 4:00:00 ----------------------------------------------------------- Total 8:00:00 "); } }