Skip to main content

alpm_types/
file_type.rs

1//! File type 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, IntoStaticStr, VariantNames};
9use winnow::{
10    Parser,
11    ascii::alpha1,
12    error::{ContextError, ErrMode, StrContext, StrContextValue},
13};
14
15/// The identifier of a file type used in ALPM.
16///
17/// These identifiers are used in the file names of file types such as binary packages (see
18/// [alpm-package]), source packages and repository sync databases (see alpm-repo-db).
19///
20/// [alpm-package]: https://alpm.archlinux.page/specifications/alpm-package.7.html
21#[derive(
22    AsRefStr, Clone, Copy, Debug, Display, EnumString, Eq, IntoStaticStr, PartialEq, VariantNames,
23)]
24#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
25#[cfg_attr(feature = "serde", serde(untagged))]
26pub enum FileTypeIdentifier {
27    /// The identifier for [alpm-package] files.
28    ///
29    /// [alpm-package]: https://alpm.archlinux.page/specifications/alpm-package.7.html
30    #[cfg_attr(feature = "serde", serde(rename = "pkg"))]
31    #[strum(to_string = "pkg")]
32    BinaryPackage,
33
34    /// The identifier for alpm-repo-db files.
35    #[cfg_attr(feature = "serde", serde(rename = "db"))]
36    #[strum(to_string = "db")]
37    RepositorySyncDatabase,
38
39    /// The identifier for source package files.
40    #[cfg_attr(feature = "serde", serde(rename = "src"))]
41    #[strum(to_string = "src")]
42    SourcePackage,
43}
44
45impl AlpmParser for FileTypeIdentifier {
46    /// Recognizes a [`FileTypeIdentifier`] in a string slice.
47    ///
48    /// # Errors
49    ///
50    /// Returns an error if `input` does not begin with a valid variant
51    /// of a [`FileTypeIdentifier`].
52    fn parser(input: &mut &str) -> Result<Self, ErrMode<ContextError>> {
53        alpha1
54            .try_map(FileTypeIdentifier::from_str)
55            .context(StrContext::Label("file type identifier"))
56            .context_with(iter_str_context!([FileTypeIdentifier::VARIANTS]))
57            .parse_next(input)
58    }
59
60    fn delimiter_error_context<'a, O, P>(
61        parser: P,
62    ) -> impl Parser<&'a str, O, ErrMode<ContextError>>
63    where
64        P: Parser<&'a str, O, ErrMode<ContextError>>,
65    {
66        parser
67            .context(StrContext::Label("file type identifier"))
68            .context(StrContext::Expected(StrContextValue::Description(
69                "a string consisting of alphabetic characters",
70            )))
71    }
72}