apple_clis/shared/identifiers/
model_name.rs

1use crate::prelude::*;
2
3/// Isomorphic to [DeviceName].
4/// [Deserialize]s and [Serialize]s from a [String] representation.
5#[derive(
6	Debug, Clone, PartialEq, derive_more::Display, derive_more::From, Serialize, Deserialize,
7)]
8#[serde(try_from = "String")]
9#[serde(into = "String")]
10pub enum ModelName {
11	IPhone(IPhoneVariant),
12
13	IPad(IPadVariant),
14
15	#[from(ignore)]
16	#[doc = include_doc!(todo)]
17	UnImplemented(String),
18}
19
20impl From<ModelName> for String {
21	#[tracing::instrument(level = "trace", skip(variant))]
22	fn from(variant: ModelName) -> Self {
23		variant.to_string()
24	}
25}
26
27impl TryFrom<&str> for ModelName {
28	type Error = <Self as FromStr>::Err;
29
30	fn try_from(value: &str) -> std::prelude::v1::Result<Self, Self::Error> {
31		value.parse()
32	}
33}
34
35impl TryFrom<String> for ModelName {
36	type Error = <Self as FromStr>::Err;
37
38	fn try_from(value: String) -> std::prelude::v1::Result<Self, Self::Error> {
39		value.parse()
40	}
41}
42
43impl_from_str_nom!(ModelName);
44
45impl ModelName {
46	pub fn is_iphone(&self) -> bool {
47		matches!(self, ModelName::IPhone(_))
48	}
49	pub fn is_ipad(&self) -> bool {
50		matches!(self, ModelName::IPad(_))
51	}
52
53	pub fn parsed_successfully(&self) -> bool {
54		!matches!(self, ModelName::UnImplemented(_))
55	}
56}
57
58impl NomFromStr for ModelName {
59	fn nom_from_str(input: &str) -> IResult<&str, Self> {
60		alt((
61			map(IPadVariant::nom_from_str, ModelName::from),
62			map(IPhoneVariant::nom_from_str, ModelName::from),
63			map(rest, |s: &str| ModelName::UnImplemented(s.to_owned())),
64		))(input)
65	}
66}
67
68#[cfg(test)]
69mod tests {
70	use crate::shared::assert_nom_parses;
71
72	use super::ModelName;
73
74	#[test]
75	fn model_names_parse() {
76		let examples = include!(concat!(
77			env!("CARGO_MANIFEST_DIR"),
78			"/tests/model-names.json"
79		));
80		assert_nom_parses::<ModelName>(examples, |input| input.parsed_successfully());
81	}
82}