apple_clis/shared/identifiers/device_name/
iphone.rs1use crate::prelude::*;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumDiscriminants, PartialOrd, Ord)]
6pub enum IPhoneVariant {
7 SE {
8 generation: Generation,
9 },
10
11 Number {
12 num: NonZeroU8,
13 plus: bool,
14 pro: bool,
15 max: bool,
16 },
17}
18
19impl NomFromStr for IPhoneVariant {
20 #[tracing::instrument(level = "trace", skip(input))]
21 fn nom_from_str(input: &str) -> IResult<&str, Self> {
22 let (remaining, discriminate) = preceded(
23 ws(tag("iPhone")),
24 cut(alt((
25 value(IPhoneVariantDiscriminants::SE, ws(tag("SE"))),
26 value(IPhoneVariantDiscriminants::Number, peek(ws(digit1))),
27 ))),
28 )(input)?;
29
30 #[cfg(test)]
31 trace!(
32 ?discriminate,
33 ?remaining,
34 "Discriminant found for parsing [IPhoneVariant]"
35 );
36
37 match discriminate {
38 IPhoneVariantDiscriminants::SE => {
39 let (remaining, generation) = Generation::nom_from_str(remaining)?;
40 Ok((remaining, IPhoneVariant::SE { generation }))
41 }
42 IPhoneVariantDiscriminants::Number => {
43 let (remaining, num) = NonZeroU8::nom_from_str(remaining)?;
44 let (remaining, plus) = alt((value(true, ws(tag("Plus"))), success(false)))(remaining)?;
45 let (remaining, pro) = alt((value(true, ws(tag("Pro"))), success(false)))(remaining)?;
46 let (remaining, max) = alt((value(true, ws(tag("Max"))), success(false)))(remaining)?;
47 Ok((
48 remaining,
49 IPhoneVariant::Number {
50 num,
51 plus,
52 pro,
53 max,
54 },
55 ))
56 }
57 }
58 }
59}
60
61impl Display for IPhoneVariant {
62 #[tracing::instrument(level = "trace", skip(self, f))]
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 match self {
65 IPhoneVariant::SE { generation } => write!(f, "iPhone SE {}", generation),
66 IPhoneVariant::Number {
67 num,
68 plus,
69 pro,
70 max,
71 } => {
72 write!(f, "iPhone {}", num)?;
73 if *plus {
74 write!(f, " Plus")?;
75 }
76 if *pro {
77 write!(f, " Pro")?;
78 }
79 if *max {
80 write!(f, " Max")?;
81 }
82 Ok(())
83 }
84 }
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[test]
93 fn iphone_ordering() {
94 let old = IPhoneVariant::SE {
95 generation: Generation::testing_num(1.try_into().unwrap()),
96 };
97 let new = IPhoneVariant::Number {
98 num: NonZeroU8::new(69).unwrap(),
99 plus: true,
100 pro: true,
101 max: true,
102 };
103 assert!(new > old);
104 }
105}