svgtypes/
aspect_ratio.rs
1use crate::{Error, Stream};
5
6#[allow(missing_docs)]
10#[derive(Clone, Copy, PartialEq, Eq, Debug)]
11pub enum Align {
12 None,
13 XMinYMin,
14 XMidYMin,
15 XMaxYMin,
16 XMinYMid,
17 XMidYMid,
18 XMaxYMid,
19 XMinYMax,
20 XMidYMax,
21 XMaxYMax,
22}
23
24#[derive(Clone, Copy, PartialEq, Eq, Debug)]
30pub struct AspectRatio {
31 pub defer: bool,
35 pub align: Align,
37 pub slice: bool,
42}
43
44impl std::str::FromStr for AspectRatio {
45 type Err = Error;
46
47 fn from_str(text: &str) -> Result<Self, Error> {
48 let mut s = Stream::from(text);
49
50 s.skip_spaces();
51
52 let defer = s.starts_with(b"defer");
53 if defer {
54 s.advance(5);
55 s.consume_byte(b' ')?;
56 s.skip_spaces();
57 }
58
59 let start = s.pos();
60 let align = s.consume_ascii_ident();
61 let align = match align {
62 "none" => Align::None,
63 "xMinYMin" => Align::XMinYMin,
64 "xMidYMin" => Align::XMidYMin,
65 "xMaxYMin" => Align::XMaxYMin,
66 "xMinYMid" => Align::XMinYMid,
67 "xMidYMid" => Align::XMidYMid,
68 "xMaxYMid" => Align::XMaxYMid,
69 "xMinYMax" => Align::XMinYMax,
70 "xMidYMax" => Align::XMidYMax,
71 "xMaxYMax" => Align::XMaxYMax,
72 _ => return Err(Error::UnexpectedData(s.calc_char_pos_at(start))),
73 };
74
75 s.skip_spaces();
76
77 let mut slice = false;
78 if !s.at_end() {
79 let start = s.pos();
80 let v = s.consume_ascii_ident();
81 match v {
82 "meet" => {}
83 "slice" => slice = true,
84 "" => {}
85 _ => return Err(Error::UnexpectedData(s.calc_char_pos_at(start))),
86 };
87 }
88
89 Ok(AspectRatio {
90 defer,
91 align,
92 slice,
93 })
94 }
95}
96
97impl Default for AspectRatio {
98 #[inline]
99 fn default() -> Self {
100 AspectRatio {
101 defer: false,
102 align: Align::XMidYMid,
103 slice: false,
104 }
105 }
106}
107
108#[rustfmt::skip]
109#[cfg(test)]
110mod tests {
111 use super::*;
112 use std::str::FromStr;
113
114 macro_rules! test {
115 ($name:ident, $text:expr, $result:expr) => (
116 #[test]
117 fn $name() {
118 let v = AspectRatio::from_str($text).unwrap();
119 assert_eq!(v, $result);
120 }
121 )
122 }
123
124 test!(parse_1, "none", AspectRatio {
125 defer: false,
126 align: Align::None,
127 slice: false,
128 });
129
130 test!(parse_2, "defer none", AspectRatio {
131 defer: true,
132 align: Align::None,
133 slice: false,
134 });
135
136 test!(parse_3, "xMinYMid", AspectRatio {
137 defer: false,
138 align: Align::XMinYMid,
139 slice: false,
140 });
141
142 test!(parse_4, "xMinYMid slice", AspectRatio {
143 defer: false,
144 align: Align::XMinYMid,
145 slice: true,
146 });
147
148 test!(parse_5, "xMinYMid meet", AspectRatio {
149 defer: false,
150 align: Align::XMinYMid,
151 slice: false,
152 });
153}