apple_clis/shared/identifiers/
screen_size.rs1use std::hash::Hash;
2
3use crate::prelude::*;
4
5pub use maybe::MaybeScreenSize;
6
7mod maybe {
8 use crate::prelude::*;
9
10 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
13 pub struct MaybeScreenSize(Option<ScreenSize>);
14
15 impl MaybeScreenSize {
16 pub fn as_ref(&self) -> Option<&ScreenSize> {
17 self.0.as_ref()
18 }
19
20 pub fn get(&self) -> Option<&ScreenSize> {
21 self.as_ref()
22 }
23 }
24
25 impl Display for MaybeScreenSize {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 if let Some(screen_size) = self.0.as_ref() {
28 write!(f, " {}", screen_size)
29 } else {
30 Ok(())
31 }
32 }
33 }
34
35 impl NomFromStr for MaybeScreenSize {
36 fn nom_from_str(input: &str) -> IResult<&str, Self> {
37 map(opt(ScreenSize::nom_from_str), MaybeScreenSize)(input)
38 }
39 }
40
41 #[cfg(test)]
42 mod test {
43 }
44}
45
46#[derive(Debug, Clone, Copy, Eq, PartialOrd, Ord)]
47pub struct ScreenSize {
48 ten_inches: u16,
50 short: bool,
53 brackets: bool,
56}
57
58impl PartialEq for ScreenSize {
59 fn eq(&self, other: &Self) -> bool {
60 self.ten_inches == other.ten_inches
61 }
62}
63
64impl Hash for ScreenSize {
65 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
66 self.ten_inches.hash(state);
67 }
68}
69
70impl ScreenSize {
71 #[stability::unstable(feature = "construction")]
83 pub fn long_brackets(inches: f32) -> Self {
84 let inches = inches * 10.0;
85
86 Self {
87 ten_inches: inches as u16,
88 short: false,
89 brackets: true,
90 }
91 }
92
93 #[stability::unstable(feature = "construction")]
105 pub fn long_bracketless(inches: f32) -> Self {
106 let inches = inches * 10.0;
107
108 Self {
109 ten_inches: inches as u16,
110 short: false,
111 brackets: false,
112 }
113 }
114
115 #[stability::unstable(feature = "construction")]
127 pub fn short_brackets(inches: f32) -> Self {
128 let inches = inches * 10.0;
129
130 Self {
131 ten_inches: inches as u16,
132 short: true,
133 brackets: true,
134 }
135 }
136
137 #[stability::unstable(feature = "construction")]
149 pub fn short_bracketless(inches: f32) -> Self {
150 let inches = inches * 10.0;
151
152 Self {
153 ten_inches: inches as u16,
154 short: true,
155 brackets: false,
156 }
157 }
158
159 pub fn inches(&self) -> f32 {
160 self.ten_inches as f32 / 10.0
161 }
162}
163
164fn brackets_long(input: &str) -> IResult<&str, ScreenSize> {
165 delimited(
166 ws(tag("(")),
167 map(float, ScreenSize::long_brackets),
168 ws(tag("-inch)")),
169 )(input)
170}
171
172fn bracketless_long(input: &str) -> IResult<&str, ScreenSize> {
173 terminated(map(float, ScreenSize::long_bracketless), ws(tag("-inch")))(input)
174}
175
176fn brackets_short(input: &str) -> IResult<&str, ScreenSize> {
177 delimited(
178 ws(tag("(")),
179 map(float, ScreenSize::short_brackets),
180 ws(tag("\")")),
181 )(input)
182}
183
184fn bracketless_short(input: &str) -> IResult<&str, ScreenSize> {
185 terminated(map(float, ScreenSize::short_bracketless), ws(tag("\"")))(input)
186}
187
188impl NomFromStr for ScreenSize {
189 #[tracing::instrument(level = "trace", skip(input))]
190 fn nom_from_str(input: &str) -> IResult<&str, Self> {
191 alt((
192 brackets_long,
193 brackets_short,
194 bracketless_long,
195 bracketless_short,
196 ))(input)
197 }
198}
199
200impl Display for ScreenSize {
201 #[tracing::instrument(level = "trace", skip(self, f))]
202 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
203 match (self.brackets, self.short) {
204 (true, false) => write!(f, "({}-inch)", self.inches()),
205 (true, true) => write!(f, "({}\")", self.inches()),
206 (false, true) => write!(f, "{}\"", self.inches()),
207 (false, false) => write!(f, "{}-inch", self.inches()),
208 }
209 }
210}
211
212#[cfg(test)]
213mod tests {
214 use crate::shared::assert_nom_parses;
215
216 use super::*;
217
218 #[test]
219 fn screen_size_hardcoded() {
220 let examples = ["(5.5-inch)", "(11-inch)", "(6.1\")", "13-inch", "11-inch"];
221 assert_nom_parses::<ScreenSize>(examples, |_| true)
222 }
223
224 #[test]
225 fn screen_size_ordering() {
226 let small = ScreenSize::long_brackets(5.0);
227 let large = ScreenSize::short_brackets(6.0);
228 assert!(large > small);
229
230 let small = ScreenSize::long_brackets(5.0);
231 let large = ScreenSize::short_brackets(6.0);
232 assert!(large > small);
233 }
234}