Skip to main content

confium_registry/
error.rs

1//! Error model for the registry client.
2//!
3//! Mirrors the snafu-based conventions used across the workspace
4//! (`confium-core`, `confium-store`). Public so callers can match on the
5//! concrete variants when surfacing CLI messages.
6
7use snafu::Snafu;
8
9pub type Result<T> = std::result::Result<T, Error>;
10
11#[derive(Snafu, Debug)]
12#[snafu(visibility(pub))]
13pub enum Error {
14    #[snafu(display("registry entry not found: {path}"))]
15    NotFound { path: String },
16
17    #[snafu(display("failed to parse TOML at {path}: {source}"))]
18    TomlParse {
19        path: String,
20        source: toml::de::Error,
21    },
22
23    #[snafu(display("failed to serialize TOML: {source}"))]
24    TomlSerialize { source: toml::ser::Error },
25
26    #[snafu(display("registry fetch failed for {path}: {message}"))]
27    Fetch { path: String, message: String },
28
29    #[snafu(display("plugin '{name}' not found in registry index"))]
30    PluginNotFound { name: String },
31
32    #[snafu(display("version '{version}' not found for plugin '{name}'"))]
33    VersionNotFound { name: String, version: String },
34
35    #[snafu(display("I/O error: {message}: {source}"))]
36    Io {
37        message: String,
38        source: std::io::Error,
39    },
40
41    #[snafu(display("artifact download failed: {message}"))]
42    Download { message: String },
43
44    #[snafu(display("hash mismatch for {name}-{version}: expected {expected}, got {actual}"))]
45    HashMismatch {
46        name: String,
47        version: String,
48        expected: String,
49        actual: String,
50    },
51
52    #[snafu(display("no trusted publisher signed plugin '{name}'"))]
53    UntrustedPlugin { name: String },
54
55    #[snafu(display("failed to load RNP library: {message}"))]
56    RnpLoad { message: String },
57
58    #[snafu(display("RNP signature verification failed: {message}"))]
59    RnpVerify { message: String },
60
61    #[snafu(display("signature file '{path}' is not ASCII-armored or binary PGP"))]
62    SignatureFormat { path: String },
63
64    #[snafu(display("public key file '{path}' is not a valid OpenPGP public key"))]
65    PublicKeyFormat { path: String },
66
67    #[snafu(display("invalid PGP signature: {message}"))]
68    SignatureInvalid { message: String },
69
70    #[snafu(display("PGP verification subprocess failed: {message}"))]
71    VerificationSubprocess { message: String },
72
73    #[snafu(display("invalid registry path: {path}"))]
74    InvalidPath { path: String },
75
76    #[snafu(display("plugin '{name}' is not installed"))]
77    NotInstalled { name: String },
78
79    #[snafu(display("config error: {message}"))]
80    Config { message: String },
81}
82
83impl Error {
84    /// Convenience constructor for the I/O variant that pairs an
85    /// `io::Error` with a human-readable explanation.
86    pub fn io(source: std::io::Error, message: impl Into<String>) -> Self {
87        Error::Io {
88            message: message.into(),
89            source,
90        }
91    }
92}