lewp_css/domain/at_rules/font_face/
font_feature_setting.rs1use {
5 crate::CustomParseError,
6 cssparser::{ParseError, Parser},
7};
8
9#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
10pub struct FontFeatureSetting(pub String, pub u32);
11
12impl FontFeatureSetting {
13 pub(crate) fn parse<'i, 't>(
14 input: &mut Parser<'i, 't>,
15 ) -> Result<Self, ParseError<'i, CustomParseError<'i>>> {
16 let openTypeFeatureTag = {
17 let openTypeFeatureTag = input.expect_string()?;
18 if openTypeFeatureTag.len() != 4 {
19 return Err(ParseError::from(
20 CustomParseError::FontFeatureSettingOpenTypeFeatureTagMustBeFourCharacters(
21 openTypeFeatureTag.clone(),
22 ),
23 ));
24 }
25
26 for character in openTypeFeatureTag.chars() {
27 if character <= '\x20' || character > '\x7E' {
28 return Err(ParseError::from(
29 CustomParseError::FontFeatureSettingOpenTypeFeatureTagMustBePrintableAscii(
30 openTypeFeatureTag.clone(),
31 ),
32 ));
33 }
34 }
35
36 openTypeFeatureTag.as_ref().into()
37 };
38
39 if let Ok(integer) = input.r#try(|input| input.expect_integer()) {
40 if integer < 0 {
41 Err(ParseError::from(
42 CustomParseError::FontFeatureSettingIntegerMustBePositive(
43 integer,
44 ),
45 ))
46 } else {
47 Ok(FontFeatureSetting(openTypeFeatureTag, integer as u32))
48 }
49 } else {
50 let ident = input.expect_ident()?;
51
52 match_ignore_ascii_case! {
53 ident,
54
55 "on" => Ok(FontFeatureSetting(openTypeFeatureTag, 1)),
56
57 "off" => Ok(FontFeatureSetting(openTypeFeatureTag, 0)),
58
59 _ => Err(ParseError::from(CustomParseError::FontFeatureSettingIfNotAnIntegerMustBeOnOrOff(ident.clone())))
60 }
61 }
62 }
63}