1use crate::{
4 errors::{APIError, CatBridgeError, NetworkError, NetworkParseError},
5 fsemul::{
6 pcfs::errors::{PcfsApiError, SataProtocolError},
7 sdio::errors::{SdioApiError, SdioNetworkError, SdioProtocolError},
8 },
9};
10use bytes::Bytes;
11use miette::Diagnostic;
12#[cfg(feature = "nus")]
13use reqwest::Error as HttpError;
14use std::path::PathBuf;
15use thiserror::Error;
16#[cfg(feature = "nus")]
17use url::ParseError as UrlParseError;
18
19#[derive(Diagnostic, Error, Debug)]
21#[non_exhaustive]
22pub enum FSEmulAPIError {
23 #[error("File descriptors have already been opened, we cannot change our strategy now!")]
24 #[diagnostic(code(cat_dev::api::fsemul::cannot_swap_fd_strategy))]
25 CannotSwapFdStrategy,
27 #[error("NUS clients cannot be set once a file has been opened!")]
28 #[diagnostic(code(cat_dev::api::fsemul::cannot_set_nus_client))]
29 CannotSetNUS,
31 #[error("DLF Address is too large ({0:016X}) to be inserted ({1:016X})")]
33 #[diagnostic(code(cat_dev::api::fsemul::dlf_address_too_large))]
34 DlfAddressTooLarge(u128, u128),
35 #[error("DLF Paths _MUST_ be able tto be encoded as UTF-8, this file path was not: {0:02X?}")]
36 #[diagnostic(code(cat_dev::api::fsemul::dlf_path_forced_utf8))]
37 DlfPathMustBeUtf8(Bytes),
38 #[error("DLF files must have an ending address that appears _last_, and is an empty string.")]
41 #[diagnostic(code(cat_dev::api::fsemul::dlf_must_have_ending))]
42 DlfMustHaveEnding,
43 #[error(
44 "You tried to place a disk item past the current ending, please update the ending, before updating the new item."
45 )]
46 #[diagnostic(code(cat_dev::api::fsemul::dlf_update_ending_first))]
47 DlfUpsertEndingFirst,
48 #[cfg(feature = "nus")]
49 #[error("Failure talking to NUS over HTTP: {0:?}")]
50 #[diagnostic(code(cat_dev::api::fsemul::nus_http_error))]
51 NUSHttpError(#[from] HttpError),
52 #[cfg(feature = "nus")]
53 #[error("Failure parsing URL for talking with nus: {0:?}")]
54 #[diagnostic(code(cat_dev::api::fsemul::nus_url_parse_error))]
55 NUSURLError(#[from] UrlParseError),
56 #[error("Failed to interact with path, file must be open first: {0:?}")]
57 #[diagnostic(code(cat_dev::api::fsemul::path_not_open))]
58 PathNotOpen(PathBuf),
59 #[error(transparent)]
60 #[diagnostic(transparent)]
61 Pcfs(#[from] PcfsApiError),
62 #[error(transparent)]
63 #[diagnostic(transparent)]
64 Sdio(#[from] SdioApiError),
65}
66
67impl From<FSEmulAPIError> for CatBridgeError {
68 fn from(value: FSEmulAPIError) -> Self {
69 Self::API(value.into())
70 }
71}
72
73impl From<PcfsApiError> for APIError {
74 fn from(value: PcfsApiError) -> Self {
75 Self::FSEmul(value.into())
76 }
77}
78impl From<PcfsApiError> for CatBridgeError {
79 fn from(value: PcfsApiError) -> Self {
80 Self::API(value.into())
81 }
82}
83
84impl From<SdioApiError> for APIError {
85 fn from(value: SdioApiError) -> Self {
86 Self::FSEmul(value.into())
87 }
88}
89impl From<SdioApiError> for CatBridgeError {
90 fn from(value: SdioApiError) -> Self {
91 Self::API(value.into())
92 }
93}
94
95#[derive(Diagnostic, Error, Debug, PartialEq, Eq)]
97pub enum FSEmulFSError {
98 #[error(
100 "We can't find the path to store fsemul configuration, please use explicit paths instead."
101 )]
102 #[diagnostic(code(cat_dev::fs::fsemul::cant_find_path))]
103 CantFindPath,
104 #[error("We can't find the root Cafe SDK folder, please use explicit paths instead.")]
106 #[diagnostic(code(cat_dev::fs::fsemul::cant_find_cafe_sdk_path))]
107 CantFindCafeSdkPath,
108 #[error("The Cafe SDK Path does not have the appropriate MLC path directories.")]
110 #[diagnostic(code(cat_dev::fs::fsemul::corrupt_cafe_sdk_path))]
111 CafeSdkPathCorrupt,
112 #[error(
114 "While parsing a disk layout file we ran into a line which is not in the format of: `<hex address>,\"<path>\"`: {0}"
115 )]
116 #[diagnostic(code(cat_dev::fs::fsemul::corrupt_dlf_line))]
117 DlfCorruptLine(String),
118 #[error("DLF files must have a blank final line, but was: {0}")]
120 #[diagnostic(code(cat_dev::fs::fsemul::corrupt_dlf_final_line))]
121 DlfCorruptFinalLine(String),
122 #[error(
124 "While parsing a disk layout file, the first line should be a version string (e.g. `v1.00`), which this was not: {0}"
125 )]
126 #[diagnostic(code(cat_dev::fs::fsemul::corrupt_dlf_version_line))]
127 DlfCorruptVersionLine(String),
128}
129impl From<FSEmulFSError> for CatBridgeError {
130 fn from(value: FSEmulFSError) -> Self {
131 Self::FS(value.into())
132 }
133}
134
135#[derive(Diagnostic, Error, Debug, PartialEq, Eq)]
137pub enum FSEmulNetworkError {
138 #[error(transparent)]
139 #[diagnostic(transparent)]
140 Sdio(#[from] SdioNetworkError),
141}
142
143impl From<FSEmulNetworkError> for CatBridgeError {
144 fn from(value: FSEmulNetworkError) -> Self {
145 Self::Network(value.into())
146 }
147}
148
149impl From<SdioNetworkError> for NetworkError {
150 fn from(value: SdioNetworkError) -> Self {
151 Self::FSEmul(value.into())
152 }
153}
154impl From<SdioNetworkError> for CatBridgeError {
155 fn from(value: SdioNetworkError) -> Self {
156 Self::Network(value.into())
157 }
158}
159
160#[derive(Diagnostic, Error, Debug, PartialEq, Eq)]
162pub enum FSEmulProtocolError {
163 #[error(transparent)]
164 #[diagnostic(transparent)]
165 PcfsSata(#[from] SataProtocolError),
166 #[error(transparent)]
167 #[diagnostic(transparent)]
168 Sdio(#[from] SdioProtocolError),
169}
170
171impl From<FSEmulProtocolError> for NetworkError {
172 fn from(value: FSEmulProtocolError) -> Self {
173 Self::Parse(value.into())
174 }
175}
176impl From<FSEmulProtocolError> for CatBridgeError {
177 fn from(value: FSEmulProtocolError) -> Self {
178 Self::Network(value.into())
179 }
180}
181
182impl From<SataProtocolError> for NetworkParseError {
183 fn from(value: SataProtocolError) -> Self {
184 Self::FSEmul(value.into())
185 }
186}
187impl From<SataProtocolError> for NetworkError {
188 fn from(value: SataProtocolError) -> Self {
189 Self::Parse(value.into())
190 }
191}
192impl From<SataProtocolError> for CatBridgeError {
193 fn from(value: SataProtocolError) -> Self {
194 Self::Network(value.into())
195 }
196}
197
198impl From<SdioProtocolError> for NetworkParseError {
199 fn from(value: SdioProtocolError) -> Self {
200 Self::FSEmul(value.into())
201 }
202}
203impl From<SdioProtocolError> for NetworkError {
204 fn from(value: SdioProtocolError) -> Self {
205 Self::Parse(value.into())
206 }
207}
208impl From<SdioProtocolError> for CatBridgeError {
209 fn from(value: SdioProtocolError) -> Self {
210 Self::Network(value.into())
211 }
212}