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