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 NotFound(#[backtrace] Backtrace),
126
127 #[diagnostic()]
128 #[error("Interface not ready.")]
129 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 }
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 {}