Skip to main content

treetop_bundle/
error.rs

1use crate::Diagnostic;
2use std::path::PathBuf;
3
4/// Errors produced while compiling or decoding a bundle.
5#[derive(Debug, thiserror::Error)]
6#[non_exhaustive]
7pub enum BundleError {
8    /// The input was readable but failed content validation.
9    #[error("bundle validation failed")]
10    Validation(Vec<Diagnostic>),
11    /// A manifest could not be decoded.
12    #[error("failed to parse manifest {path}: {message}")]
13    Manifest { path: PathBuf, message: String },
14    /// JSON input could not be decoded.
15    #[error("failed to parse JSON {path}: {message}")]
16    Json { path: String, message: String },
17    /// A filesystem operation failed.
18    #[error("filesystem error for {path}: {source}")]
19    Io {
20        path: PathBuf,
21        #[source]
22        source: std::io::Error,
23    },
24    /// A key could not be loaded or decoded.
25    #[error("key error: {0}")]
26    Key(String),
27    /// An encrypted private key was provided without a password.
28    #[error("the signing key is encrypted and requires a password")]
29    SigningKeyPasswordRequired,
30    /// Archive framing or structure is invalid.
31    #[error("invalid bundle archive: {0}")]
32    Archive(String),
33    /// A configured size limit was exceeded.
34    #[error("bundle {kind} size exceeds the configured limit of {limit} bytes")]
35    SizeLimit { kind: &'static str, limit: usize },
36    /// Serialization of an internally validated value failed.
37    #[error("serialization failed: {0}")]
38    Serialization(String),
39}
40
41impl BundleError {
42    /// Whether this error represents invalid user-controlled bundle content.
43    pub fn is_validation(&self) -> bool {
44        matches!(
45            self,
46            Self::Validation(_)
47                | Self::Manifest { .. }
48                | Self::Json { .. }
49                | Self::Archive(_)
50                | Self::SizeLimit { .. }
51        )
52    }
53
54    /// Return structured diagnostics when available.
55    pub fn diagnostics(&self) -> &[Diagnostic] {
56        match self {
57            Self::Validation(diagnostics) => diagnostics,
58            _ => &[],
59        }
60    }
61
62    pub(crate) fn io(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
63        Self::Io {
64            path: path.into(),
65            source,
66        }
67    }
68}
69
70pub type Result<T> = std::result::Result<T, BundleError>;