Skip to main content

bundle_standard_core/
errors.rs

1//! Typed errors with stable codes.
2
3use thiserror::Error;
4
5#[derive(Debug, Error)]
6pub enum PackError {
7    #[error("E_INVALID_FORMAT: format '{0}' not supported (only 'gtpack-legacy' in Phase A)")]
8    InvalidFormat(String),
9    #[error("E_INVALID_CONFIG: {0}")]
10    InvalidConfig(String),
11    #[error("E_ZIP: {0}")]
12    Zip(String),
13    #[error("E_SERDE: {0}")]
14    Serde(String),
15    #[error("E_MANIFEST_CBOR: {0}")]
16    ManifestCbor(String),
17}
18
19impl PackError {
20    pub fn code(&self) -> &'static str {
21        match self {
22            PackError::InvalidFormat(_) => "E_INVALID_FORMAT",
23            PackError::InvalidConfig(_) => "E_INVALID_CONFIG",
24            PackError::Zip(_) => "E_ZIP",
25            PackError::Serde(_) => "E_SERDE",
26            PackError::ManifestCbor(_) => "E_MANIFEST_CBOR",
27        }
28    }
29}
30
31impl From<serde_json::Error> for PackError {
32    fn from(e: serde_json::Error) -> Self {
33        PackError::Serde(e.to_string())
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40    #[test]
41    fn codes_stable() {
42        assert_eq!(
43            PackError::InvalidFormat("x".into()).code(),
44            "E_INVALID_FORMAT"
45        );
46        assert_eq!(
47            PackError::InvalidConfig("bad".into()).code(),
48            "E_INVALID_CONFIG"
49        );
50        assert_eq!(PackError::Zip("zip oops".into()).code(), "E_ZIP");
51        assert_eq!(PackError::Serde("decode".into()).code(), "E_SERDE");
52    }
53
54    #[test]
55    fn display_includes_code_prefix() {
56        assert_eq!(
57            PackError::InvalidFormat("custom".into()).to_string(),
58            "E_INVALID_FORMAT: format 'custom' not supported (only 'gtpack-legacy' in Phase A)"
59        );
60        assert_eq!(
61            PackError::InvalidConfig("missing".into()).to_string(),
62            "E_INVALID_CONFIG: missing"
63        );
64        assert_eq!(PackError::Zip("entry".into()).to_string(), "E_ZIP: entry");
65        assert_eq!(
66            PackError::Serde("decode".into()).to_string(),
67            "E_SERDE: decode"
68        );
69    }
70
71    #[test]
72    fn from_serde_json_error() {
73        let bad: Result<serde_json::Value, _> = serde_json::from_str("{not json");
74        let err: PackError = bad.unwrap_err().into();
75        assert_eq!(err.code(), "E_SERDE");
76        assert!(matches!(err, PackError::Serde(_)));
77    }
78}