lewp_css/domain/at_rules/font_face/
source.rs1use {
5 super::{FamilyName, FontUrlSource},
6 crate::{
7 domain::SpecifiedUrl,
8 parsers::{
9 separators::{Comma, Separated},
10 Parse,
11 ParserContext,
12 },
13 CustomParseError,
14 },
15 cssparser::{ParseError, Parser, ToCss},
16 std::fmt,
17};
18
19#[derive(Clone, Debug, Eq, PartialEq)]
21pub enum Source {
22 Url(FontUrlSource),
24
25 Local(FamilyName),
27}
28
29impl ToCss for Source {
30 fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
31 use self::Source::*;
32
33 match *self {
34 Url(ref fontUrlSource) => fontUrlSource.to_css(dest),
35 Local(ref familyName) => familyName.to_css(dest),
36 }
37 }
38}
39
40impl Separated for Source {
41 type Delimiter = Comma;
42}
43
44impl Parse for Source {
45 fn parse<'i, 't>(
46 context: &ParserContext,
47 input: &mut Parser<'i, 't>,
48 ) -> Result<Source, ParseError<'i, CustomParseError<'i>>> {
49 use self::Source::*;
50
51 if input
52 .r#try(|input| input.expect_function_matching("local"))
53 .is_ok()
54 {
55 input
56 .parse_nested_block(|input| FamilyName::parse(context, input))
57 .map(Local)
58 } else {
59 let url = SpecifiedUrl::parse(context, input)?;
60
61 let format_hints = if input
63 .r#try(|input| input.expect_function_matching("format"))
64 .is_ok()
65 {
66 input.parse_nested_block(|input| {
67 input.parse_comma_separated(|input| {
68 Ok(input.expect_string()?.as_ref().to_owned())
69 })
70 })?
71 } else {
72 vec![]
73 };
74
75 Ok(Url(FontUrlSource { url, format_hints }))
76 }
77 }
78}