1use cssparser::Parser;
4
5use crate::error::*;
6use crate::parse_identifiers;
7use crate::parsers::Parse;
8
9#[derive(Debug, Copy, Clone, PartialEq, Eq)]
13pub enum CoordUnits {
14 UserSpaceOnUse,
15 ObjectBoundingBox,
16}
17
18impl Parse for CoordUnits {
19 fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<Self, ParseError<'i>> {
20 Ok(parse_identifiers!(
21 parser,
22 "userSpaceOnUse" => CoordUnits::UserSpaceOnUse,
23 "objectBoundingBox" => CoordUnits::ObjectBoundingBox,
24 )?)
25 }
26}
27
28#[doc(hidden)]
37#[macro_export]
38macro_rules! coord_units {
39 ($name:ident, $default:expr) => {
40 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
41 pub struct $name(pub CoordUnits);
42
43 impl Default for $name {
44 fn default() -> Self {
45 $name($default)
46 }
47 }
48
49 impl From<$name> for CoordUnits {
50 fn from(u: $name) -> Self {
51 u.0
52 }
53 }
54
55 impl $crate::parsers::Parse for $name {
56 fn parse<'i>(
57 parser: &mut ::cssparser::Parser<'i, '_>,
58 ) -> Result<Self, $crate::error::ParseError<'i>> {
59 Ok($name($crate::coord_units::CoordUnits::parse(parser)?))
60 }
61 }
62 };
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 coord_units!(MyUnits, CoordUnits::ObjectBoundingBox);
70
71 #[test]
72 fn parsing_invalid_strings_yields_error() {
73 assert!(MyUnits::parse_str("").is_err());
74 assert!(MyUnits::parse_str("foo").is_err());
75 }
76
77 #[test]
78 fn parses_paint_server_units() {
79 assert_eq!(
80 MyUnits::parse_str("userSpaceOnUse").unwrap(),
81 MyUnits(CoordUnits::UserSpaceOnUse)
82 );
83 assert_eq!(
84 MyUnits::parse_str("objectBoundingBox").unwrap(),
85 MyUnits(CoordUnits::ObjectBoundingBox)
86 );
87 }
88
89 #[test]
90 fn has_correct_default() {
91 assert_eq!(MyUnits::default(), MyUnits(CoordUnits::ObjectBoundingBox));
92 }
93
94 #[test]
95 fn converts_to_coord_units() {
96 assert_eq!(
97 CoordUnits::from(MyUnits(CoordUnits::ObjectBoundingBox)),
98 CoordUnits::ObjectBoundingBox
99 );
100 }
101}