Skip to main content

alpm_srcinfo/
error.rs

1//! All error types that are exposed by this crate.
2use std::{path::PathBuf, string::FromUtf8Error};
3
4use alpm_parsers::error::{Input, ParseStack};
5use alpm_pkgbuild::error::Error as PkgbuildError;
6use fluent_i18n::t;
7use thiserror::Error;
8use winnow::error::ParseError;
9
10use crate::pkgbuild_bridge::error::BridgeError;
11#[cfg(doc)]
12use crate::{SourceInfoV1, source_info::parser::SourceInfoContent};
13
14/// The high-level error that can occur when using this crate.
15///
16/// Notably, it contains an important enum in the context of parsing:
17/// - `ParseError` is an already formatted error generated by the `winnow` parser. This effectively
18///   means that some invalid data has been encountered
19#[derive(Debug, Error)]
20#[non_exhaustive]
21pub enum Error {
22    /// ALPM type error
23    #[error("{msg}", msg = t!("error-alpm-type", { "error" => .0.to_string() }))]
24    AlpmType(#[from] alpm_types::Error),
25
26    /// IO error
27    #[error("{msg}", msg = t!("error-io", { "context" => .context, "error" => .source.to_string() }))]
28    Io {
29        /// The context in which the IO error occurred.
30        context: String,
31        /// The underlying IO error.
32        source: std::io::Error,
33    },
34
35    /// IO error with additional path info for more context.
36    #[error("{msg}", msg = t!("error-io-path", {
37        "path" => path,
38        "context" => context,
39        "error" => source.to_string()
40    }))]
41    IoPath {
42        /// The path related to the IO error.
43        path: PathBuf,
44        /// The context in which the IO error occurred.
45        context: String,
46        /// The underlying IO error.
47        source: std::io::Error,
48    },
49
50    /// UTF-8 parse error when reading the input file.
51    #[error("{msg}", msg = t!("error-invalid-utf8", { "error" => .0.to_string() }))]
52    InvalidUTF8(#[from] FromUtf8Error),
53
54    /// A section or keyword is missing for a SRCINFO schema version.
55    #[error("{msg}", msg = t!("error-missing-keyword", { "keyword" => keyword }))]
56    MissingKeyword {
57        /// The missing keyword.
58        keyword: &'static str,
59    },
60
61    /// A parsing error that occurred during winnow file parsing.
62    #[error("{msg}", msg = t!("error-parse", { "error" => .0 }))]
63    ParseError(String),
64
65    /// Unsupported schema version
66    #[error("{msg}", msg = t!("error-unsupported-schema-version", { "version" => .0 }))]
67    UnsupportedSchemaVersion(String),
68
69    /// An alpm-pkgbuild bridge error that occurred when converting a PKGBUILD to a
70    /// [`SourceInfoV1`].
71    ///
72    /// See [`PkgbuildError`] for further details.
73    #[error("{msg}", msg = t!("error-bridge", { "error" => .0.to_string() }))]
74    BridgeError(#[from] PkgbuildError),
75
76    /// A logical error occurred when transforming `alpm-pkgbuild-bridge` script output to a
77    /// [`SourceInfoV1`] struct.
78    ///
79    /// See [`BridgeError`] for further details.
80    #[error("{msg}", msg = t!("error-bridge-conversion", { "error" => .0.to_string() }))]
81    BridgeConversionError(#[from] BridgeError),
82}
83
84impl<'a> From<ParseError<Input<'a>, ParseStack<'a>>> for Error {
85    /// Converts a [`ParseError`] into an [`Error::ParseError`].
86    fn from(value: ParseError<Input<'a>, ParseStack<'a>>) -> Self {
87        // Only take the **inner** parser error of our own ParseStack error type.
88        // We don't want to hit the `Display` impl of `ParseError`.
89        Self::ParseError(value.into_inner().to_string())
90    }
91}