lewp_css/domain/at_rules/keyframes/
keyframes_name.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        domain::{Atom, CustomIdent},
7        CustomParseError,
8    },
9    cssparser::{
10        BasicParseError,
11        BasicParseErrorKind,
12        ParseError,
13        Parser,
14        ToCss,
15        Token,
16    },
17    std::{
18        fmt,
19        hash::{Hash, Hasher},
20    },
21};
22
23/// <https://drafts.csswg.org/css-animations/#typedef-keyframes-name>
24#[derive(Debug, Clone)]
25pub enum KeyframesName {
26    /// <custom-ident>
27    Ident(CustomIdent),
28
29    /// <string>
30    QuotedString(Atom),
31}
32
33impl KeyframesName {
34    /// <https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-name>
35    pub fn from_ident(value: &str) -> Self {
36        let custom_ident =
37            CustomIdent::from_ident(&value.into(), &["none"]).ok();
38        match custom_ident {
39            Some(ident) => KeyframesName::Ident(ident),
40            None => KeyframesName::QuotedString(value.into()),
41        }
42    }
43
44    /// The name as an Atom
45    pub fn as_atom(&self) -> &Atom {
46        match *self {
47            KeyframesName::Ident(ref ident) => &ident.0,
48            KeyframesName::QuotedString(ref atom) => atom,
49        }
50    }
51}
52
53impl PartialEq for KeyframesName {
54    fn eq(&self, other: &Self) -> bool {
55        self.as_atom() == other.as_atom()
56    }
57}
58
59impl Eq for KeyframesName {}
60
61impl Hash for KeyframesName {
62    fn hash<H: Hasher>(&self, state: &mut H) {
63        self.as_atom().hash(state)
64    }
65}
66
67impl ToCss for KeyframesName {
68    fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
69        match *self {
70            KeyframesName::Ident(ref ident) => ident.to_css(dest),
71            KeyframesName::QuotedString(ref atom) => atom.to_css(dest),
72        }
73    }
74}
75
76impl KeyframesName {
77    pub(crate) fn parse<'i, 't>(
78        input: &mut Parser<'i, 't>,
79    ) -> Result<Self, ParseError<'i, CustomParseError<'i>>> {
80        match input.next() {
81            Ok(&Token::Ident(ref s)) => {
82                Ok(KeyframesName::Ident(CustomIdent::from_ident(s, &["none"])?))
83            }
84            Ok(&Token::QuotedString(ref s)) => {
85                Ok(KeyframesName::QuotedString(Atom::from(s.as_ref())))
86            }
87            Ok(t) => Err(ParseError::from(BasicParseError {
88                kind: BasicParseErrorKind::UnexpectedToken(t.clone()),
89                location: input.state().source_location(),
90            })),
91            Err(e) => Err(e.into()),
92        }
93    }
94}