use cssparser::Parser;
use std::fmt;
use crate::style::{
Animatable, CssSyntaxKind, CssToken, FromCss, MakeComputed, ParseResult, ToCss,
declare_enum_from_css_impl, properties::write_css_string, tw::TailwindPropertyParser,
};
#[derive(Debug, Clone, PartialEq, Default)]
#[non_exhaustive]
pub enum BlockEllipsis {
#[default]
None,
Auto,
String(String),
}
impl MakeComputed for BlockEllipsis {}
impl Animatable for BlockEllipsis {}
impl<'i> FromCss<'i> for BlockEllipsis {
fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
return Ok(Self::None);
}
if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() {
return Ok(Self::Auto);
}
Ok(Self::String(input.expect_string_cloned()?.to_string()))
}
const VALID_TOKENS: &'static [CssToken] = &[
CssToken::Keyword("none"),
CssToken::Keyword("auto"),
CssToken::Syntax(CssSyntaxKind::String),
];
}
impl ToCss for BlockEllipsis {
fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
match self {
Self::None => dest.write_str("none"),
Self::Auto => dest.write_str("auto"),
Self::String(value) => write_css_string(dest, value),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum Continue {
#[default]
Normal,
Collapse,
}
declare_enum_from_css_impl!(
Continue,
"normal" => Continue::Normal,
"collapse" => Continue::Collapse,
);
impl Animatable for Continue {}
#[derive(Debug, Clone, PartialEq, Default)]
#[non_exhaustive]
pub struct LineClamp {
pub max_lines: Option<u32>,
pub block_ellipsis: BlockEllipsis,
pub line_continue: Continue,
}
impl LineClamp {
fn clamp(max_lines: Option<u32>, block_ellipsis: BlockEllipsis) -> Self {
Self {
max_lines,
block_ellipsis,
line_continue: Continue::Collapse,
}
}
}
impl From<u32> for LineClamp {
fn from(count: u32) -> Self {
if count >= 1 {
Self::clamp(Some(count), BlockEllipsis::Auto)
} else {
Self::default()
}
}
}
impl MakeComputed for LineClamp {}
impl<'i> FromCss<'i> for LineClamp {
fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
return Ok(Self::default());
}
let count = input.expect_integer()?;
if count < 1 {
return Ok(Self::default());
}
let block_ellipsis = if input.is_exhausted() {
BlockEllipsis::Auto
} else {
BlockEllipsis::from_css(input)?
};
Ok(Self::clamp(Some(count as u32), block_ellipsis))
}
const VALID_TOKENS: &'static [CssToken] = &[
CssToken::Keyword("none"),
CssToken::Syntax(CssSyntaxKind::Integer),
CssToken::Syntax(CssSyntaxKind::String),
];
}
impl TailwindPropertyParser for LineClamp {
fn parse_tw(token: &str) -> Option<Self> {
if token.eq_ignore_ascii_case("none") {
return Some(Self::default());
}
let count = token.parse::<u32>().ok()?;
if count == 0 {
return None;
}
Some(Self::clamp(Some(count), BlockEllipsis::Auto))
}
}