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}