Skip to main content

alpm_srcinfo/pkgbuild_bridge/
error.rs

1//! The error types used in the scope of `alpm-pkgbuild-bridge` output logic.
2
3use alpm_parsers::prelude::*;
4use alpm_pkgbuild::bridge::Keyword;
5use alpm_types::{Name, SystemArchitecture};
6use fluent_i18n::t;
7use thiserror::Error;
8use winnow::error::ParseError;
9
10#[cfg(doc)]
11use crate::SourceInfo;
12
13/// A lower-level error that may occur when converting `alpm-pkgbuild-bridge` script output into the
14/// [`SourceInfo`] format.
15#[derive(Debug, Error)]
16pub enum BridgeError {
17    /// ALPM type parse error
18    #[error(transparent)]
19    AlpmType(#[from] alpm_types::Error),
20
21    /// No `pkgname` has been specified.
22    #[error("{msg}", msg = t!("error-bridge-no-name"))]
23    NoName,
24
25    /// A package name is not valid.
26    #[error("{msg}", msg = t!("error-bridge-invalid-package-name", {
27        "name" => name,
28        "error" => error.to_string()
29    }))]
30    InvalidPackageName {
31        /// The invalid package name.
32        name: String,
33        /// The source error.
34        error: alpm_types::Error,
35    },
36
37    /// A `package` function has been declared for a split package, but it is not defined in
38    /// `pkgname`.
39    #[error("{msg}", msg = t!("error-bridge-undeclared-package", { "name" => .0 }))]
40    UndeclaredPackageName(String),
41
42    /// An unused package function exists for an undeclared [alpm-split-package].
43    ///
44    /// [alpm-split-package]: https://alpm.archlinux.page/specifications/alpm-split-package.7.html
45    #[error("{msg}", msg = t!("error-bridge-unused-package-function", { "name" => .0.to_string() }))]
46    UnusedPackageFunction(Name),
47
48    /// A type parser fails on a certain keyword.
49    #[error("{msg}", msg = t!("error-bridge-missing-required-keyword", { "keyword" => keyword.to_string() }))]
50    MissingRequiredKeyword {
51        /// The keyword that cannot be parsed.
52        keyword: Keyword,
53    },
54
55    /// A type parser fails on a certain keyword.
56    #[error("{msg}", msg = t!("error-bridge-parse-error", {
57        "keyword" => keyword.to_string(),
58        "error" => error
59    }))]
60    ParseError {
61        /// The keyword that cannot be parsed.
62        keyword: Keyword,
63        /// The error message.
64        error: String,
65    },
66
67    /// A variable is expected to be of a different type.
68    /// E.g. `String` when an `Array` is expected.
69    #[error("{msg}", msg = t!("error-bridge-wrong-variable-type", {
70        "keyword" => keyword,
71        "expected" => expected,
72        "actual" => actual
73    }))]
74    WrongVariableType {
75        /// The name of the keyword for which a wrong variable type is used.
76        keyword: String,
77        /// The expected type of variable.
78        expected: String,
79        /// The actual type of variable.
80        actual: String,
81    },
82
83    /// A keyword has an architecture suffix even though it shouldn't have one.
84    #[error("{msg}", msg = t!("error-bridge-unexpected-arch", {
85        "keyword" => keyword.to_string(),
86        "suffix" => suffix.to_string()
87    }))]
88    UnexpectedArchitecture {
89        /// The keyword for which an unexpected architecture suffix is found.
90        keyword: Keyword,
91        /// The architecture that is found for the `keyword`.
92        suffix: SystemArchitecture,
93    },
94
95    /// A keyword that cannot be cleared is attempted to be cleared.
96    #[error("{msg}", msg = t!("error-bridge-unclearable-value", { "keyword" => keyword.to_string() }))]
97    UnclearableValue {
98        /// The keyword that is attempted to be cleared.
99        keyword: Keyword,
100    },
101
102    /// A keyword should have only a single value, but an array is found.
103    #[error("{msg}", msg = t!("error-bridge-unexpected-array", {
104        "keyword" => keyword.to_string(),
105        "values" => values.iter().map(|s| format!("\"{s}\"")).collect::<Vec<_>>().join(", ")
106    }))]
107    UnexpectedArray {
108        /// The keyword for which a single value should be used.
109        keyword: Keyword,
110        /// The values that are used for the `keyword`.
111        values: Vec<String>,
112    },
113}
114
115impl<'a> From<(Keyword, ParseError<Input<'a>, ParseStack<'a>>)> for BridgeError {
116    /// Converts a tuple of ([`Keyword`] and [`ParseError`]) into a [`BridgeError::ParseError`].
117    fn from(value: (Keyword, ParseError<Input<'a>, ParseStack<'a>>)) -> Self {
118        Self::ParseError {
119            keyword: value.0,
120            error: value.1.to_string(),
121        }
122    }
123}