apple_clis/shared/identifiers/device_name/
iphone.rs

1use crate::prelude::*;
2
3/// Ordered from oldest to newest.
4/// newest > oldest
5#[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}