lewp_css/domain/at_rules/font_face/
source.rs

1// This file is part of css. It is subject to the license terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/css/master/COPYRIGHT. No part of predicator, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
2// Copyright © 2017 The developers of css. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/css/master/COPYRIGHT.
3
4use {
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/// A source for a font-face rule.
20#[derive(Clone, Debug, Eq, PartialEq)]
21pub enum Source {
22    /// A `url()` source.
23    Url(FontUrlSource),
24
25    /// A `local()` source.
26    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            // Parsing optional format()
62            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}