lewp_css/domain/at_rules/font_feature_values/
vector_values.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    crate::{
6        parsers::{Parse, ParserContext},
7        CustomParseError,
8    },
9    cssparser::{BasicParseError, ParseError, Parser, ToCss, Token},
10    std::fmt,
11};
12
13/// A @font-feature-values block declaration value that keeps a list of values.
14#[derive(Clone, Debug, PartialEq)]
15pub struct VectorValues(pub Vec<u32>);
16
17impl Parse for VectorValues {
18    fn parse<'i, 't>(
19        _context: &ParserContext,
20        input: &mut Parser<'i, 't>,
21    ) -> Result<VectorValues, ParseError<'i, CustomParseError<'i>>> {
22        let mut vec = vec![];
23        loop {
24            match input.next() {
25                Ok(&Token::Number {
26                    int_value: Some(a), ..
27                }) if a >= 0 => {
28                    vec.push(a as u32);
29                }
30
31                // It can't be anything other than number.
32                Ok(unexpectedToken) => {
33                    return CustomParseError::unexpectedToken(unexpectedToken)
34                }
35
36                Err(_) => break,
37            }
38        }
39
40        if vec.is_empty() {
41            return Err(ParseError::from(BasicParseError {
42                kind: cssparser::BasicParseErrorKind::EndOfInput,
43                location: input.state().source_location(),
44            }));
45        }
46
47        Ok(VectorValues(vec))
48    }
49}
50
51impl ToCss for VectorValues {
52    fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
53        let mut iter = self.0.iter();
54        let first = iter.next();
55        if let Some(first) = first {
56            first.to_css(dest)?;
57            for value in iter {
58                dest.write_char(' ')?;
59                value.to_css(dest)?;
60            }
61        }
62        Ok(())
63    }
64}