Skip to main content

alpm_repo_db/
error.rs

1//! Error handling.
2
3use std::path::PathBuf;
4
5use fluent_i18n::t;
6use winnow::error::{ContextError, ParseError};
7
8use crate::desc::SectionKeyword;
9
10/// The error that can occur when working with the [`alpm-repo-desc`] files.
11///
12/// [`alpm-repo-desc`]: https://alpm.archlinux.page/specifications/alpm-repo-desc.5.html
13#[derive(Debug, thiserror::Error)]
14#[non_exhaustive]
15pub enum Error {
16    /// IO error.
17    #[error("{msg}", msg = t!("error-io", { "context" => context, "source" => source.to_string() }))]
18    Io {
19        /// The context in which the error occurred.
20        ///
21        /// This is meant to complete the sentence "I/O error while ".
22        context: String,
23        /// The source error.
24        source: std::io::Error,
25    },
26
27    /// An I/O error occurred at a path.
28    #[error("{msg}", msg = t!("error-io-path", {
29        "path" => path.display().to_string(),
30        "context" => context,
31        "source" => source.to_string(),
32    }))]
33    IoPath {
34        /// The path at which the error occurred.
35        path: PathBuf,
36        /// The context in which the error occurred.
37        ///
38        /// This is meant to complete the sentence "I/O error at path while ".
39        context: String,
40        /// The source error.
41        source: std::io::Error,
42    },
43
44    /// I/O error while reading a buffer.
45    #[error("{msg}", msg = t!("error-io-read", { "context" => context, "source" => source.to_string() }))]
46    IoRead {
47        /// The context in which the error occurred.
48        ///
49        /// This is meant to complete the sentence "Read error while ".
50        context: String,
51        /// The error source.
52        source: std::io::Error,
53    },
54
55    /// A winnow parser for a type didn't work and produced an error.
56    #[error("{msg}", msg = t!("error-parse", { "error" => .0 }))]
57    ParseError(String),
58
59    /// A section is missing in the parsed data.
60    #[error("{msg}", msg = t!("error-missing-section", { "section" => .0.to_string() }))]
61    MissingSection(SectionKeyword),
62
63    /// A section is duplicated in the parsed data.
64    #[error("{msg}", msg = t!("error-duplicate-section", { "section" => .0.to_string() }))]
65    DuplicateSection(SectionKeyword),
66
67    /// A section is invalid for the given schema version.
68    #[error("{msg}", msg = t!("error-invalid-section-for-version", { "section" => section.to_string(), "version" => version.to_string() }))]
69    InvalidSectionForVersion {
70        /// The section keyword.
71        section: SectionKeyword,
72        /// The schema version.
73        version: u8,
74    },
75
76    /// Found an empty section that should either contain value(s) or be omitted.
77    #[error("{msg}", msg = t!("error-empty-section", { "section" => .0.to_string() }))]
78    EmptySection(SectionKeyword),
79
80    /// No input file given.
81    #[error("{msg}", msg = t!("error-no-input-file"))]
82    NoInputFile,
83
84    #[cfg(feature = "cli")]
85    /// JSON error.
86    #[error("{msg}", msg = t!("error-json", { "context" => context, "source" => source.to_string() }))]
87    Json {
88        /// The context in which the error occurred.
89        ///
90        /// This is meant to complete the sentence "JSON error while ".
91        context: String,
92        /// The error source.
93        source: serde_json::Error,
94    },
95
96    /// Unsupported schema version.
97    #[error("{msg}", msg = t!("error-unsupported-schema-version", { "version" => .0 }))]
98    UnsupportedSchemaVersion(String),
99
100    /// Failed to parse v1 or v2.
101    #[error("{msg}", msg = t!("error-invalid-format"))]
102    InvalidFormat,
103}
104
105impl<'a> From<ParseError<&'a str, ContextError>> for Error {
106    /// Converts a [`ParseError`] into an [`Error::ParseError`].
107    fn from(value: ParseError<&'a str, ContextError>) -> Self {
108        Self::ParseError(value.to_string())
109    }
110}