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}