use cssparser::{Parser, Token};
use typed_builder::TypedBuilder;
use crate::layout::style::{
Animatable, CssSyntaxKind, CssToken, FromCss, MakeComputed, ParseResult,
declare_enum_from_css_impl, unexpected_token,
};
#[derive(Debug, Clone, Copy, PartialEq, Default, TypedBuilder)]
#[non_exhaustive]
#[builder(field_defaults(default))]
pub struct TextFit {
pub mode: TextFitMode,
pub target: TextFitTarget,
pub limit: Option<f32>,
}
impl MakeComputed for TextFit {}
impl Animatable for TextFit {}
impl<'i> FromCss<'i> for TextFit {
fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
let mut mode = None;
let mut target = None;
let mut limit = None;
while !input.is_exhausted() {
if let Ok(parsed) = input.try_parse(TextFitMode::from_css) {
if mode.replace(parsed).is_some() {
return Err(input.new_error_for_next_token());
}
continue;
}
if let Ok(parsed) = input.try_parse(TextFitTarget::from_css) {
if target.replace(parsed).is_some() {
return Err(input.new_error_for_next_token());
}
continue;
}
let location = input.current_source_location();
let token = input.next()?;
match token {
Token::Percentage { unit_value, .. } if limit.replace(unit_value.max(0.0)).is_none() => {}
_ => return Err(unexpected_token!(location, token)),
}
}
Ok(Self {
mode: mode.unwrap_or_default(),
target: target.unwrap_or_default(),
limit,
})
}
const VALID_TOKENS: &'static [CssToken] = &[
CssToken::Keyword("none"),
CssToken::Keyword("grow"),
CssToken::Keyword("shrink"),
CssToken::Keyword("consistent"),
CssToken::Keyword("per-line"),
CssToken::Keyword("per-line-all"),
CssToken::Syntax(CssSyntaxKind::Percentage),
];
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum TextFitMode {
#[default]
None,
Grow,
Shrink,
}
declare_enum_from_css_impl!(
TextFitMode,
"none" => TextFitMode::None,
"grow" => TextFitMode::Grow,
"shrink" => TextFitMode::Shrink,
);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum TextFitTarget {
#[default]
Consistent,
PerLine,
PerLineAll,
}
declare_enum_from_css_impl!(
TextFitTarget,
"consistent" => TextFitTarget::Consistent,
"per-line" => TextFitTarget::PerLine,
"per-line-all" => TextFitTarget::PerLineAll,
);