Skip to main content

rustbridge_bundle/
error.rs

1//! Error types for bundle operations.
2
3use thiserror::Error;
4
5/// Errors that can occur during bundle operations.
6#[derive(Debug, Error)]
7pub enum BundleError {
8    /// I/O error during file operations.
9    #[error("I/O error: {0}")]
10    Io(#[from] std::io::Error),
11
12    /// JSON parsing or serialization error.
13    #[error("JSON error: {0}")]
14    Json(#[from] serde_json::Error),
15
16    /// ZIP archive error.
17    #[error("Archive error: {0}")]
18    Zip(#[from] zip::result::ZipError),
19
20    /// Manifest validation error.
21    #[error("Invalid manifest: {0}")]
22    InvalidManifest(String),
23
24    /// Checksum mismatch.
25    #[error("Checksum mismatch for {path}: expected {expected}, got {actual}")]
26    ChecksumMismatch {
27        path: String,
28        expected: String,
29        actual: String,
30    },
31
32    /// Platform not supported in this bundle.
33    #[error("Platform not supported: {0}")]
34    UnsupportedPlatform(String),
35
36    /// Missing required file in bundle.
37    #[error("Missing required file: {0}")]
38    MissingFile(String),
39
40    /// Library file not found.
41    #[error("Library not found: {0}")]
42    LibraryNotFound(String),
43
44    /// Requested variant not found for platform.
45    #[error("Variant '{variant}' not found for platform '{platform}'")]
46    VariantNotFound { platform: String, variant: String },
47
48    /// Invalid variant name format.
49    #[error("Invalid variant name '{0}': must be lowercase alphanumeric with hyphens")]
50    InvalidVariantName(String),
51
52    /// Schema mismatch when combining bundles.
53    #[error("Schema mismatch: {0}")]
54    SchemaMismatch(String),
55}
56
57#[cfg(test)]
58mod tests {
59    #![allow(non_snake_case)]
60
61    use super::*;
62
63    #[test]
64    fn BundleError___io___displays_message() {
65        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
66        let err: BundleError = io_err.into();
67
68        assert!(err.to_string().contains("I/O error"));
69    }
70
71    #[test]
72    fn BundleError___invalid_manifest___displays_message() {
73        let err = BundleError::InvalidManifest("missing name".to_string());
74
75        assert_eq!(err.to_string(), "Invalid manifest: missing name");
76    }
77
78    #[test]
79    fn BundleError___checksum_mismatch___displays_all_fields() {
80        let err = BundleError::ChecksumMismatch {
81            path: "lib/test.so".to_string(),
82            expected: "sha256:expected".to_string(),
83            actual: "sha256:actual".to_string(),
84        };
85
86        let msg = err.to_string();
87        assert!(msg.contains("lib/test.so"));
88        assert!(msg.contains("sha256:expected"));
89        assert!(msg.contains("sha256:actual"));
90    }
91
92    #[test]
93    fn BundleError___unsupported_platform___displays_platform() {
94        let err = BundleError::UnsupportedPlatform("linux-arm".to_string());
95
96        assert_eq!(err.to_string(), "Platform not supported: linux-arm");
97    }
98
99    #[test]
100    fn BundleError___missing_file___displays_path() {
101        let err = BundleError::MissingFile("manifest.json".to_string());
102
103        assert_eq!(err.to_string(), "Missing required file: manifest.json");
104    }
105
106    #[test]
107    fn BundleError___library_not_found___displays_path() {
108        let err = BundleError::LibraryNotFound("/path/to/lib.so".to_string());
109
110        assert_eq!(err.to_string(), "Library not found: /path/to/lib.so");
111    }
112
113    #[test]
114    fn BundleError___from_io_error___converts() {
115        let io_err = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "access denied");
116        let bundle_err: BundleError = io_err.into();
117
118        assert!(matches!(bundle_err, BundleError::Io(_)));
119    }
120
121    #[test]
122    fn BundleError___variant_not_found___displays_details() {
123        let err = BundleError::VariantNotFound {
124            platform: "linux-x86_64".to_string(),
125            variant: "debug".to_string(),
126        };
127
128        let msg = err.to_string();
129        assert!(msg.contains("debug"));
130        assert!(msg.contains("linux-x86_64"));
131    }
132
133    #[test]
134    fn BundleError___invalid_variant_name___displays_name() {
135        let err = BundleError::InvalidVariantName("INVALID".to_string());
136
137        assert_eq!(
138            err.to_string(),
139            "Invalid variant name 'INVALID': must be lowercase alphanumeric with hyphens"
140        );
141    }
142
143    #[test]
144    fn BundleError___schema_mismatch___displays_reason() {
145        let err = BundleError::SchemaMismatch("checksums differ".to_string());
146
147        assert_eq!(err.to_string(), "Schema mismatch: checksums differ");
148    }
149}