arch_pkg_text/srcinfo/field/parse.rs
1use super::{Field, RawField};
2use derive_more::{Display, Error};
3
4/// Error when attempt to parse a [`Field`] with [`TryFrom`].
5#[derive(Debug, Display, Clone, Copy, Error)]
6pub enum ParseFieldError<ParseNameError, ParseArchitectureError> {
7 Name(ParseNameError),
8 Architecture(ParseArchitectureError),
9}
10
11type ParseError<'a, Name, Architecture> =
12 ParseFieldError<<&'a str as TryInto<Name>>::Error, <&'a str as TryInto<Architecture>>::Error>;
13
14type ParseResult<'a, Name, Architecture> =
15 Result<Field<Name, Architecture>, ParseError<'a, Name, Architecture>>;
16
17impl<Name, Architecture> Field<Name, Architecture> {
18 /// Parse a [`Field`] from [`str`].
19 /// ```
20 /// # use arch_pkg_text::srcinfo::{Field, FieldName, ParsedField};
21 /// # use pretty_assertions::assert_eq;
22 /// let parsed_field: ParsedField<&str> = Field::parse("source_x86_64").unwrap();
23 /// assert_eq!(parsed_field.name(), &FieldName::Source);
24 /// assert_eq!(parsed_field.architecture_str(), Some("x86_64"));
25 /// ```
26 pub fn parse<'a>(input: &'a str) -> ParseResult<'a, Name, Architecture>
27 where
28 &'a str: TryInto<Name> + TryInto<Architecture>,
29 {
30 RawField::parse_raw(input).to_parsed()
31 }
32}
33
34/// Parse a [`Field`] from [`str`].
35impl<'a, Name, Architecture> TryFrom<&'a str> for Field<Name, Architecture>
36where
37 &'a str: TryInto<Name> + TryInto<Architecture>,
38{
39 type Error = ParseError<'a, Name, Architecture>;
40 fn try_from(value: &'a str) -> ParseResult<'a, Name, Architecture> {
41 RawField::parse_raw(value).to_parsed()
42 }
43}
44
45impl<'a> RawField<'a> {
46 /// Parse a [`RawField`] from a [`str`].
47 ///
48 /// **Without architecture:**
49 ///
50 /// ```
51 /// # use arch_pkg_text::srcinfo::RawField;
52 /// # use pretty_assertions::assert_eq;
53 /// let raw_field = RawField::parse_raw("source");
54 /// assert_eq!(raw_field.name_str(), "source");
55 /// assert_eq!(raw_field.architecture_str(), None);
56 /// ```
57 ///
58 /// **With architecture:**
59 ///
60 /// ```
61 /// # use arch_pkg_text::srcinfo::RawField;
62 /// # use pretty_assertions::assert_eq;
63 /// let raw_field = RawField::parse_raw("source_x86_64");
64 /// assert_eq!(raw_field.name_str(), "source");
65 /// assert_eq!(raw_field.architecture_str(), Some("x86_64"));
66 /// ```
67 pub fn parse_raw(input: &'a str) -> Self {
68 let (name, architecture) = match input.split_once('_') {
69 Some((name, architecture)) => (name, Some(architecture)),
70 None => (input, None),
71 };
72 RawField { name, architecture }
73 }
74
75 /// Try converting a [`RawField`] into a [`Field<Name, Architecture>`].
76 ///
77 /// ```
78 /// # use arch_pkg_text::srcinfo::{FieldName, ParsedField, RawField};
79 /// # use pretty_assertions::assert_eq;
80 /// let raw_field = RawField::parse_raw("source_x86_64");
81 /// let parsed_field: ParsedField<&str> = raw_field.to_parsed().unwrap();
82 /// assert_eq!(parsed_field.name(), &FieldName::Source);
83 /// assert_eq!(parsed_field.architecture_str(), Some("x86_64"));
84 /// ```
85 pub fn to_parsed<Name, Architecture>(&self) -> ParseResult<'a, Name, Architecture>
86 where
87 &'a str: TryInto<Name> + TryInto<Architecture>,
88 {
89 let &RawField { name, architecture } = self;
90 let name: Name = name.try_into().map_err(ParseFieldError::Name)?;
91 let architecture: Option<Architecture> = architecture
92 .map(TryInto::try_into)
93 .transpose()
94 .map_err(ParseFieldError::Architecture)?;
95 Ok(Field { name, architecture })
96 }
97}