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}