svgtypes/
viewbox.rs
1use crate::Stream;
5
6#[derive(Clone, Copy, Debug)]
8pub enum ViewBoxError {
9 InvalidNumber,
11
12 InvalidSize,
14}
15
16impl std::fmt::Display for ViewBoxError {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 match *self {
19 ViewBoxError::InvalidNumber => {
20 write!(f, "viewBox contains an invalid number")
21 }
22 ViewBoxError::InvalidSize => {
23 write!(f, "viewBox has a negative or zero size")
24 }
25 }
26 }
27}
28
29impl std::error::Error for ViewBoxError {
30 fn description(&self) -> &str {
31 "a viewBox parsing error"
32 }
33}
34
35#[allow(missing_docs)]
39#[derive(Clone, Copy, PartialEq, Debug)]
40pub struct ViewBox {
41 pub x: f64,
42 pub y: f64,
43 pub w: f64,
44 pub h: f64,
45}
46
47impl ViewBox {
48 pub fn new(x: f64, y: f64, w: f64, h: f64) -> Self {
50 ViewBox { x, y, w, h }
51 }
52}
53
54impl std::str::FromStr for ViewBox {
55 type Err = ViewBoxError;
56
57 fn from_str(text: &str) -> Result<Self, ViewBoxError> {
58 let mut s = Stream::from(text);
59
60 let x = s
61 .parse_list_number()
62 .map_err(|_| ViewBoxError::InvalidNumber)?;
63 let y = s
64 .parse_list_number()
65 .map_err(|_| ViewBoxError::InvalidNumber)?;
66 let w = s
67 .parse_list_number()
68 .map_err(|_| ViewBoxError::InvalidNumber)?;
69 let h = s
70 .parse_list_number()
71 .map_err(|_| ViewBoxError::InvalidNumber)?;
72
73 if w <= 0.0 || h <= 0.0 {
74 return Err(ViewBoxError::InvalidSize);
75 }
76
77 Ok(ViewBox::new(x, y, w, h))
78 }
79}
80
81#[rustfmt::skip]
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use std::str::FromStr;
86
87 macro_rules! test {
88 ($name:ident, $text:expr, $result:expr) => (
89 #[test]
90 fn $name() {
91 let v = ViewBox::from_str($text).unwrap();
92 assert_eq!(v, $result);
93 }
94 )
95 }
96
97 test!(parse_1, "-20 30 100 500", ViewBox::new(-20.0, 30.0, 100.0, 500.0));
98
99 macro_rules! test_err {
100 ($name:ident, $text:expr, $result:expr) => (
101 #[test]
102 fn $name() {
103 assert_eq!(ViewBox::from_str($text).unwrap_err().to_string(), $result);
104 }
105 )
106 }
107
108 test_err!(parse_err_1, "qwe", "viewBox contains an invalid number");
109 test_err!(parse_err_2, "10 20 30 0", "viewBox has a negative or zero size");
110 test_err!(parse_err_3, "10 20 0 40", "viewBox has a negative or zero size");
111 test_err!(parse_err_4, "10 20 0 0", "viewBox has a negative or zero size");
112 test_err!(parse_err_5, "10 20 -30 0", "viewBox has a negative or zero size");
113 test_err!(parse_err_6, "10 20 30 -40", "viewBox has a negative or zero size");
114 test_err!(parse_err_7, "10 20 -30 -40", "viewBox has a negative or zero size");
115}