svgtypes/
enable_background.rs

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