pub const TOKEN_COMMENT: char = '|'; pub const TOKEN_NOTE: char = '-'; pub const TOKEN_TASK_DONE: char = 'x'; pub const TOKEN_TASK_UNDONE: char = 'o'; #[derive(Debug, PartialEq, Copy, Clone, serde::Deserialize, serde::Serialize)] pub enum Kind { /// Comments are mostly guides and useful information for the author of the /// journal. /// You should use them in such a manner that if you delete them right after /// completing the month, you won't lose any information worth keeping. /// /// for example, this could be a legend. or a calendar view. Comment, /// An atomic unit that indicates that demands no particular action. Note, /// An atomic unit that once demanded an action. TaskDone, /// An atomic unit that demands action. TaskUndone, } impl Kind { pub fn token(self) -> char { match self { Kind::Comment => TOKEN_COMMENT, Kind::Note => TOKEN_NOTE, Kind::TaskDone => TOKEN_TASK_DONE, Kind::TaskUndone => TOKEN_TASK_UNDONE, } } pub fn prefix(self) -> String { format!("{}\t", self.token()) } } #[derive(Debug, PartialEq, Clone, serde::Deserialize, serde::Serialize)] pub struct Bullet { /// Specifies the kind of bullet this is. /// This also specifies The token pub kind: Kind, /// Main content of the bullet. pub sentence: String, /// Tags pub tags: Option>, } impl Bullet { pub fn basic_format(&self) -> String { let item = format!("{}{}", self.kind.prefix(), &self.sentence); let Some(tags) = &self.tags else { return item; }; format!( "{item}\t{}", tags.iter() .map(|x| format!("#{x}")) .collect::>() .join(" ") ) } } #[cfg(test)] mod tests { use rstest::rstest; use super::*; #[rstest] #[case(Bullet{ kind: Kind::TaskUndone, sentence:"Something amazing is happening.".to_string() , tags: Some(vec!["tag1".to_owned(), "tag2".to_owned()]) },"o\tSomething amazing is happening.\t#tag1 #tag2")] #[case(Bullet{ kind: Kind::Note, sentence:"Something amazing is happening.".to_string() , tags: None },"-\tSomething amazing is happening.")] fn basic_format_test(#[case] input: Bullet, #[case] expect: &str) { assert_eq!(input.basic_format(), expect.to_owned()) } }