use super::css::StyleSheet; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Item { contents: Vec<ItemContent>, layout: StyleSheet, } impl std::fmt::Display for Item { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "{}", self.contents .iter() .map(|ic| ic.to_string()) .collect::<Vec<String>>() .join("") ) } } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct ItemContent { tag: String, text: Option<String>, contents: Option<Vec<ItemContent>>, } impl std::fmt::Display for ItemContent { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let body = match &self.contents { Some(contents) => contents .iter() .map(|item| item.to_string()) .collect::<Vec<String>>() .join(""), None => self .text .as_ref() .expect("Either contents or text field must be provided") .to_string(), }; write!(f, "<{}>{}</{}>", self.tag, body, self.tag) } } #[cfg(test)] mod test_items { use super::*; use std::collections::HashMap; #[test] fn text_item_content_to_string() { let item_content = ItemContent { tag: String::from("p"), text: Some(String::from("Hello")), contents: None, }; assert_eq!(item_content.to_string(), "<p>Hello</p>") } #[test] fn complex_item_content_to_string() { let item_content = ItemContent { tag: String::from("p"), text: None, contents: Some(vec![ ItemContent { tag: String::from("span"), text: Some(String::from("Hello ")), contents: None, }, ItemContent { tag: String::from("b"), text: Some(String::from("World")), contents: None, }, ]), }; assert_eq!( item_content.to_string(), "<p><span>Hello </span><b>World</b></p>" ) } #[test] fn item_to_string() { let item = Item { layout: StyleSheet(HashMap::new()), contents: vec![ ItemContent { tag: String::from("span"), text: Some(String::from("Hello ")), contents: None, }, ItemContent { tag: String::from("b"), text: Some(String::from("World")), contents: None, }, ], }; assert_eq!(item.to_string(), "<span>Hello </span><b>World</b>") } }