takumi_css/style/properties/
line_clamp.rs1use cssparser::Parser;
2use std::fmt;
3
4use crate::style::{
5 CssSyntaxKind, CssToken, FromCss, MakeComputed, ParseResult, ToCss, properties::write_css_string,
6 tw::TailwindPropertyParser,
7};
8
9#[derive(Debug, Clone, PartialEq)]
10#[non_exhaustive]
12pub struct LineClamp {
13 pub count: u32,
15 pub ellipsis: Option<String>,
17}
18
19impl MakeComputed for LineClamp {}
20
21impl TailwindPropertyParser for LineClamp {
22 fn parse_tw(token: &str) -> Option<Self> {
23 if token.eq_ignore_ascii_case("none") {
24 return Some(LineClamp {
25 count: 0,
26 ellipsis: None,
27 });
28 }
29 let count = token.parse::<u32>().ok()?;
30 if count == 0 {
31 return None;
32 }
33 Some(LineClamp {
34 count,
35 ellipsis: None,
36 })
37 }
38}
39
40impl From<u32> for LineClamp {
41 fn from(count: u32) -> Self {
42 Self {
43 count,
44 ellipsis: None,
45 }
46 }
47}
48
49impl<'i> FromCss<'i> for LineClamp {
50 fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
51 if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
52 return Ok(LineClamp {
53 count: 0,
54 ellipsis: None,
55 });
56 }
57 let count = input.try_parse(Parser::expect_integer)?;
58 let ellipsis = input.try_parse(Parser::expect_string_cloned).ok();
59
60 Ok(LineClamp {
61 count: count as u32,
62 ellipsis: ellipsis.map(|s| s.to_string()),
63 })
64 }
65
66 const VALID_TOKENS: &'static [CssToken] = &[
67 CssToken::Keyword("none"),
68 CssToken::Syntax(CssSyntaxKind::Integer),
69 CssToken::Syntax(CssSyntaxKind::String),
70 ];
71}
72
73impl ToCss for LineClamp {
74 fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
75 if self.count == 0 && self.ellipsis.is_none() {
76 return dest.write_str("none");
77 }
78 match &self.ellipsis {
79 Some(e) => {
80 write!(dest, "{} ", self.count)?;
81 write_css_string(dest, e)
82 }
83 None => write!(dest, "{}", self.count),
84 }
85 }
86}