Skip to main content

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 core::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(Self::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(Self::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(Self::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 alloc::string::ToString;
75    use core::str::FromStr;
76
77    #[test]
78    fn parse_1() {
79        assert_eq!(EnableBackground::from_str("accumulate").unwrap(), EnableBackground::Accumulate);
80    }
81
82    #[test]
83    fn parse_2() {
84        assert_eq!(EnableBackground::from_str("  accumulate  ").unwrap(), EnableBackground::Accumulate);
85    }
86
87    #[test]
88    fn parse_3() {
89        assert_eq!(EnableBackground::from_str("new").unwrap(), EnableBackground::New);
90    }
91
92    #[test]
93    fn parse_4() {
94        assert_eq!(EnableBackground::from_str("  new  ").unwrap(), EnableBackground::New);
95    }
96
97    #[test]
98    fn parse_5() {
99        assert_eq!(EnableBackground::from_str("new 1 2 3 4").unwrap(),
100                   EnableBackground::NewWithRegion { x: 1.0, y: 2.0, width: 3.0, height: 4.0 });
101    }
102
103    #[test]
104    fn err_1() {
105        assert_eq!(EnableBackground::from_str(" accumulate b ").unwrap_err().to_string(),
106                   "unexpected data at position 13");
107    }
108
109    #[test]
110    fn err_2() {
111        assert_eq!(EnableBackground::from_str(" new b ").unwrap_err().to_string(),
112                   "invalid number at position 6");
113    }
114
115    #[test]
116    fn err_3() {
117        assert_eq!(EnableBackground::from_str("new 1 2 3").unwrap_err().to_string(),
118                   "unexpected end of stream");
119    }
120
121    #[test]
122    fn err_4() {
123        assert_eq!(EnableBackground::from_str("new 1 2 3 4 5").unwrap_err().to_string(),
124                   "unexpected data at position 13");
125    }
126
127    #[test]
128    fn err_5() {
129        assert_eq!(EnableBackground::from_str("new 0 0 0 0").unwrap_err().to_string(),
130                   "invalid value");
131    }
132}