Skip to main content

alpm_types/package/
validation.rs

1//! Package validation handling.
2
3use std::str::FromStr;
4
5use alpm_parsers::{iter_str_context, traits::AlpmParser};
6use serde::{Deserialize, Serialize};
7use strum::{AsRefStr, Display, EnumString, VariantNames};
8use winnow::{
9    Parser,
10    ascii::alphanumeric1,
11    error::{ContextError, ErrMode, StrContext, StrContextValue},
12};
13
14/// The validation method used during installation of a package.
15///
16/// A validation method can ensure the integrity of a package.
17/// Certain methods (i.e. [`PackageValidation::Pgp`]) can also be used to ensure a package's
18/// authenticity.
19///
20/// # Examples
21///
22/// Parsing from strings:
23///
24/// ```
25/// use std::str::FromStr;
26///
27/// use alpm_types::PackageValidation;
28///
29/// # fn main() -> Result<(), alpm_types::Error> {
30/// assert_eq!(
31///     PackageValidation::from_str("none")?,
32///     PackageValidation::None
33/// );
34/// assert_eq!(PackageValidation::from_str("md5")?, PackageValidation::Md5);
35/// assert_eq!(
36///     PackageValidation::from_str("sha256")?,
37///     PackageValidation::Sha256
38/// );
39/// assert_eq!(PackageValidation::from_str("pgp")?, PackageValidation::Pgp);
40///
41/// // Invalid values return an error.
42/// assert!(PackageValidation::from_str("crc32").is_err());
43/// # Ok(())
44/// # }
45/// ```
46///
47/// Displaying and serializing:
48///
49/// ```
50/// use alpm_types::PackageValidation;
51///
52/// # fn main() -> Result<(), alpm_types::Error> {
53/// assert_eq!(PackageValidation::Md5.to_string(), "md5");
54/// assert_eq!(
55///     serde_json::to_string(&PackageValidation::Sha256).expect("Serialization failed"),
56///     "\"Sha256\""
57/// );
58/// # Ok(())
59/// # }
60/// ```
61#[derive(
62    Clone, Debug, PartialEq, Deserialize, Serialize, EnumString, Display, AsRefStr, VariantNames,
63)]
64#[strum(serialize_all = "lowercase")]
65pub enum PackageValidation {
66    /// The package integrity and authenticity is **not validated**.
67    None,
68    /// The package is validated against an accompanying **MD5 hash digest**.
69    Md5,
70    /// The package is validated against an accompanying **SHA-256 hash digest**.
71    Sha256,
72    /// The package is validated using **PGP signatures**.
73    Pgp,
74}
75
76impl AlpmParser for PackageValidation {
77    /// Recognizes a [`PackageValidation`] in a string slice.
78    ///
79    /// # Errors
80    ///
81    /// Returns an error if `input` does not begin with a valid variant
82    /// of [`PackageValidation`].
83    fn parser(input: &mut &str) -> Result<Self, ErrMode<ContextError>> {
84        alphanumeric1
85            .try_map(PackageValidation::from_str)
86            .context(StrContext::Label("package validation method"))
87            .context_with(iter_str_context!([PackageValidation::VARIANTS]))
88            .parse_next(input)
89    }
90
91    fn delimiter_error_context<'a, O, P>(
92        parser: P,
93    ) -> impl Parser<&'a str, O, ErrMode<ContextError>>
94    where
95        P: Parser<&'a str, O, ErrMode<ContextError>>,
96    {
97        parser
98            .context(StrContext::Label("package validation method"))
99            .context(StrContext::Expected(StrContextValue::Description(
100                "a string consisting of alphanumeric characters",
101            )))
102    }
103}