1use crate::{Error, Stream};
2
3/// Representation of the [`enable-background`] attribute.
4///
5/// [`enable-background`]: https://www.w3.org/TR/SVG11/filters.html#EnableBackgroundProperty
6#[derive(Clone, Copy, PartialEq, Debug)]
7#[allow(missing_docs)]
8pub enum EnableBackground {
9 Accumulate,
10 New,
11 NewWithRegion {
12 x: f64,
13 y: f64,
14 width: f64,
15 height: f64,
16 },
17}
18
19impl std::str::FromStr for EnableBackground {
20 type Err = Error;
21
22 fn from_str(text: &str) -> Result<Self, Self::Err> {
23 let mut s = Stream::from(text);
24 s.skip_spaces();
25 if s.starts_with(b"accumulate") {
26 s.advance(10);
27 s.skip_spaces();
28 if !s.at_end() {
29 return Err(Error::UnexpectedData(s.calc_char_pos()));
30 }
31
32 Ok(EnableBackground::Accumulate)
33 } else if s.starts_with(b"new") {
34 s.advance(3);
35 s.skip_spaces();
36 if s.at_end() {
37 return Ok(EnableBackground::New);
38 }
39
40 let x = s.parse_list_number()?;
41 let y = s.parse_list_number()?;
42 let width = s.parse_list_number()?;
43 let height = s.parse_list_number()?;
44
45 s.skip_spaces();
46 if !s.at_end() {
47 return Err(Error::UnexpectedData(s.calc_char_pos()));
48 }
49
50 // Region size must be valid;
51 if !(width > 0.0 && height > 0.0) {
52 return Err(Error::InvalidValue);
53 }
54
55 Ok(EnableBackground::NewWithRegion {
56 x,
57 y,
58 width,
59 height,
60 })
61 } else {
62 Err(Error::InvalidValue)
63 }
64 }
65}
66
67#[rustfmt::skip]
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use std::str::FromStr;
72
73 #[test]
74 fn parse_1() {
75 assert_eq!(EnableBackground::from_str("accumulate").unwrap(), EnableBackground::Accumulate);
76 }
77
78 #[test]
79 fn parse_2() {
80 assert_eq!(EnableBackground::from_str(" accumulate ").unwrap(), EnableBackground::Accumulate);
81 }
82
83 #[test]
84 fn parse_3() {
85 assert_eq!(EnableBackground::from_str("new").unwrap(), EnableBackground::New);
86 }
87
88 #[test]
89 fn parse_4() {
90 assert_eq!(EnableBackground::from_str(" new ").unwrap(), EnableBackground::New);
91 }
92
93 #[test]
94 fn parse_5() {
95 assert_eq!(EnableBackground::from_str("new 1 2 3 4").unwrap(),
96 EnableBackground::NewWithRegion { x: 1.0, y: 2.0, width: 3.0, height: 4.0 });
97 }
98
99 #[test]
100 fn err_1() {
101 assert_eq!(EnableBackground::from_str(" accumulate b ").unwrap_err().to_string(),
102 "unexpected data at position 13");
103 }
104
105 #[test]
106 fn err_2() {
107 assert_eq!(EnableBackground::from_str(" new b ").unwrap_err().to_string(),
108 "invalid number at position 6");
109 }
110
111 #[test]
112 fn err_3() {
113 assert_eq!(EnableBackground::from_str("new 1 2 3").unwrap_err().to_string(),
114 "unexpected end of stream");
115 }
116
117 #[test]
118 fn err_4() {
119 assert_eq!(EnableBackground::from_str("new 1 2 3 4 5").unwrap_err().to_string(),
120 "unexpected data at position 13");
121 }
122
123 #[test]
124 fn err_5() {
125 assert_eq!(EnableBackground::from_str("new 0 0 0 0").unwrap_err().to_string(),
126 "invalid value");
127 }
128}
129