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