loadsmith_registry/error.rs
1use std::error::Error as StdError;
2
3use camino::Utf8PathBuf;
4
5/// Errors returned by registry operations.
6///
7/// Wraps I/O errors, Thunderstore client errors, zip errors, JSON errors, and
8/// several registry-specific error conditions such as missing packages,
9/// missing or invalid metadata, and file-not-found.
10///
11/// # Examples
12///
13/// ```rust
14/// use loadsmith_registry::Error;
15///
16/// let err = Error::PackageNotFound;
17/// assert_eq!(err.to_string(), "package not found");
18///
19/// let io_err = Error::Io(std::io::Error::new(std::io::ErrorKind::NotFound, "missing"));
20/// assert!(io_err.to_string().contains("I/O error"));
21/// ```
22#[derive(Debug, thiserror::Error)]
23pub enum Error {
24 /// An I/O error occurred while reading a file or directory.
25 #[error("I/O error")]
26 Io(#[from] std::io::Error),
27
28 /// An error from the Thunderstore API client.
29 #[error("thunderstore client error")]
30 Thunderstore(#[from] thunderstore::Error),
31
32 /// An error while reading a zip archive.
33 #[error("zip error")]
34 Zip(#[from] zip::result::ZipError),
35
36 /// An error while serialising or deserialising JSON metadata.
37 #[error("json error")]
38 Json(#[from] serde_json::Error),
39
40 /// A registry with the given identifier was not found in the set.
41 #[error("registry not found: {0}")]
42 RegistryNotFound(String),
43
44 /// An opaque, boxed error from an external source.
45 #[error(transparent)]
46 Other(Box<dyn StdError + Send + Sync>),
47
48 /// A registry operation required metadata but none was provided.
49 #[error("registry requires metadata, but none was provided")]
50 MissingMetadata,
51
52 /// The metadata provided to the registry was not valid for the expected schema.
53 #[error("registry got invalid metadata")]
54 InvalidMetadata(#[source] serde_json::Error),
55
56 /// A required file does not exist at the given path.
57 #[error("file not found: {0}")]
58 FileNotFound(Utf8PathBuf),
59
60 /// The file at the given path is not a recognised type.
61 #[error("invalid file type: {0}")]
62 InvalidFileType(Utf8PathBuf),
63
64 /// The requested package could not be found in the registry.
65 #[error("package not found")]
66 PackageNotFound,
67
68 /// The requested package version could not be found.
69 #[error("package version not found")]
70 VersionNotFound,
71
72 /// A local package source is missing its `manifest.json`.
73 #[error("local package has no manifest")]
74 LocalManifestMissing,
75
76 /// A local package's version could not be determined and no `source_version` was supplied.
77 #[error(
78 "version could not be determined from local package, please specify a source_version in metadata"
79 )]
80 LocalVersionMissing,
81}
82
83impl Error {
84 /// Wrap an arbitrary error into the [`Error::Other`] variant.
85 ///
86 /// # Examples
87 ///
88 /// ```rust
89 /// use loadsmith_registry::Error;
90 ///
91 /// let custom = "something went wrong".to_string();
92 /// let err = Error::other(std::io::Error::new(std::io::ErrorKind::Other, custom));
93 /// assert!(err.to_string().contains("something went wrong"));
94 /// ```
95 pub fn other<E: StdError + Send + Sync + 'static>(err: E) -> Self {
96 Self::Other(Box::new(err))
97 }
98}
99
100/// Convenience alias for [`std::result::Result`] whose error type is [`Error`].
101pub type Result<T> = std::result::Result<T, Error>;