playdate_device/
error.rs

1use std::backtrace::Backtrace;
2use thiserror::Error;
3use miette::Diagnostic;
4use crate::usb::mode::Mode;
5
6
7#[derive(Error, Debug, Diagnostic)]
8pub enum Error {
9	#[error(transparent)]
10	#[diagnostic(code(my_lib::io_error))]
11	Io {
12		#[backtrace]
13		#[from]
14		source: std::io::Error,
15	},
16
17	#[error(transparent)]
18	#[diagnostic()]
19	Process {
20		#[backtrace]
21		#[from]
22		source: std::process::ExitStatusError,
23	},
24
25	#[error(transparent)]
26	#[diagnostic()]
27	Transfer {
28		#[backtrace]
29		#[from]
30		source: nusb::transfer::TransferError,
31	},
32
33	#[error(transparent)]
34	#[diagnostic()]
35	Borrow {
36		#[backtrace]
37		#[from]
38		source: std::cell::BorrowMutError,
39	},
40
41	#[error("Awaiting device timeout `{device}`.")]
42	#[diagnostic()]
43	DeviceTimeout {
44		#[backtrace]
45		backtrace: Backtrace,
46		device: crate::device::Device,
47	},
48
49	#[error("Awaiting {what} timeout.")]
50	Timeout {
51		#[backtrace]
52		backtrace: Backtrace,
53		what: String,
54	},
55
56	#[error(transparent)]
57	#[diagnostic()]
58	Utf {
59		#[backtrace]
60		#[from]
61		source: std::str::Utf8Error,
62	},
63
64	#[error(transparent)]
65	Json {
66		#[backtrace]
67		#[from]
68		source: serde_json::Error,
69	},
70
71	#[cfg(target_os = "macos")]
72	#[error(transparent)]
73	Plist {
74		#[backtrace]
75		#[from]
76		source: plist::Error,
77	},
78
79	#[cfg(target_os = "linux")]
80	#[error(transparent)]
81	Lfs {
82		#[backtrace]
83		#[from]
84		source: lfs_core::Error,
85	},
86
87	#[cfg(target_os = "windows")]
88	#[error(transparent)]
89	WinApi {
90		#[backtrace]
91		#[from]
92		source: windows::core::Error,
93	},
94
95	#[error("Chain of errors: {source}\n\t{others:#?}")]
96	#[diagnostic()]
97	Chain {
98		#[backtrace]
99		#[diagnostic(transparent)]
100		source: Box<Error>,
101		#[related]
102		#[diagnostic(transparent)]
103		others: Vec<Error>,
104	},
105
106	#[error(transparent)]
107	#[diagnostic(transparent)]
108	DeviceSerial {
109		#[backtrace]
110		#[from]
111		source: crate::device::serial::error::SerialNumberFormatError,
112	},
113
114	#[error(transparent)]
115	#[diagnostic()]
116	SerialPort {
117		#[backtrace]
118		#[from]
119		source: serialport::Error,
120	},
121
122	#[diagnostic()]
123	#[error("Device not found.")]
124	/// Device discovery error.
125	NotFound(#[backtrace] Backtrace),
126
127	#[diagnostic()]
128	#[error("Interface not ready.")]
129	/// Interface error.
130	NotReady(#[backtrace] Backtrace),
131
132	#[error("Device in the wrong state `{0:?}`.")]
133	WrongState(Mode),
134
135	#[error("Mount point not found for {0}.")]
136	MountNotFound(String),
137	// #[error("data store disconnected")]
138	// Disconnect(#[from] io::Error),
139	// #[error("the data for key `{0}` is not available")]
140	// Redaction(String),
141	// #[error("invalid header (expected {expected:?}, found {found:?})")]
142	// InvalidHeader { expected: String, found: String },
143	// #[error("unknown error")]
144	// Unknown,
145}
146
147
148impl Error {
149	#[track_caller]
150	pub fn usb_timeout(device: crate::device::Device) -> Self {
151		Self::DeviceTimeout { device,
152		                      backtrace: Backtrace::capture() }
153	}
154
155	#[track_caller]
156	pub fn timeout<S: ToString>(what: S) -> Self {
157		Self::Timeout { what: what.to_string(),
158		                backtrace: Backtrace::capture() }
159	}
160
161	#[track_caller]
162	pub fn not_found() -> Self { Self::NotFound(Backtrace::capture()) }
163	#[track_caller]
164	pub fn not_ready() -> Self { Self::NotReady(Backtrace::capture()) }
165
166	#[track_caller]
167	pub fn chain<I, A, B>(err: A, others: I) -> Self
168		where I: IntoIterator<Item = B>,
169		      A: Into<Error>,
170		      B: Into<Error> {
171		Self::Chain { source: Box::new(err.into()),
172		              others: others.into_iter().map(Into::into).collect() }
173	}
174}
175
176
177unsafe impl Sync for Error {}