1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
use crate::{Colors, Error, Image, ImageSrc, Serde, Text, TextStyle, Tree, Unit}; impl Serde<Image, String> for Image { fn de(s: String) -> Result<Image, Error> { let t = Tree::de(s)?; if t.children.len() != 1 { return Err(Error::DeserializeHtmlError( "deserialize Text failed, children's length should be 1".into(), )); } let child: Tree = match t.children.len() > 0 { true => t.children[0].borrow().to_owned(), false => Tree::default(), }; Ok(Image::new( t.attrs.get("src").unwrap_or(&"".into()).to_string(), child, )) } fn ser(&self) -> String { let t: Tree = self.into(); t.ser() } } impl Serde<ImageSrc, String> for ImageSrc { fn de(s: String) -> Result<ImageSrc, Error> { Ok(ImageSrc(s)) } fn ser(&self) -> String { format!("background-image: url({})", self.0) } } impl Serde<Text, String> for Text { fn de(s: String) -> Result<Text, Error> { let t = Tree::de(s)?; if t.children.len() != 1 { return Err(Error::DeserializeHtmlError( "deserialize Text failed, children's length should be 1".into(), )); } let text = t.children[0].borrow(); Ok(Text::new( text.attrs .get("text") .unwrap_or(&"".to_string()) .to_string(), TextStyle::de(t.attrs.get("style").unwrap_or(&"".into()).to_string())?.into(), )) } fn ser(&self) -> String { let t: Tree = self.into(); t.ser() } } impl Serde<TextStyle, String> for TextStyle { fn de(s: String) -> Result<TextStyle, Error> { let mut ts = TextStyle::default(); s.split(";").collect::<Vec<&str>>().iter().for_each(|x| { if x.len() < 1 { return; } let v = x[(x.find(":").unwrap_or(0) + 1)..].trim(); match x { k if k.contains("color") => { ts.color = Colors::de(v.into()).unwrap_or(Colors::Black) } k if k.contains("font-weight") => { ts.weight = Unit::de(v.into()).unwrap_or(Unit::None(400.0)); ts.bold = match ts.weight { Unit::None(x) => x == 700.0, _ => false, } } k if k.contains("font-style") => { ts.italic = match v { "italic" => true, _ => false, }; } k if k.contains("font-size") => { ts.size = Unit::de(v.into()).unwrap_or(Unit::Rem(1.0)) } k if k.contains("height") => { ts.height = Unit::de(v.into()).unwrap_or(Unit::Rem(1.0)) } k if k.contains("font-stretch") => { ts.stretch = Unit::de(v.into()).unwrap_or(Unit::Percent(100.0)) } _ => {} } }); Ok(ts) } fn ser(&self) -> String { format!( "color: {}; font-weight: {}; font-style: {}; font-size: {}; font-stretch: {}; line-height: {};", self.color.ser(), match self.bold { true => "700".into(), false => self.weight.ser(), }, match self.italic { true => "italic", false => "normal" }, self.size.ser(), self.stretch.ser(), self.height.ser(), ) } }