twizzler_rt_abi/
error.rs

1use core::fmt::Display;
2
3use crate::bindings::{self};
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
6#[repr(transparent)]
7pub struct RawTwzError(bindings::twz_error);
8
9impl RawTwzError {
10    pub fn category(&self) -> ErrorCategory {
11        let cat = (self.0 & bindings::ERROR_CATEGORY_MASK) >> bindings::ERROR_CATEGORY_SHIFT;
12        match cat as u16 {
13            bindings::GENERIC_ERROR => ErrorCategory::Generic,
14            bindings::ARGUMENT_ERROR => ErrorCategory::Argument,
15            bindings::RESOURCE_ERROR => ErrorCategory::Resource,
16            bindings::NAMING_ERROR => ErrorCategory::Naming,
17            bindings::OBJECT_ERROR => ErrorCategory::Object,
18            bindings::IO_ERROR => ErrorCategory::Io,
19            bindings::SECURITY_ERROR => ErrorCategory::Security,
20            _ => ErrorCategory::Uncategorized,
21        }
22    }
23
24    pub fn code(&self) -> u16 {
25        ((self.0 & bindings::ERROR_CODE_MASK) >> bindings::ERROR_CODE_SHIFT) as u16
26    }
27
28    pub fn from_parts(cat: u16, code: u16) -> Self {
29        let cat = ((cat as u64) << bindings::ERROR_CATEGORY_SHIFT) & bindings::ERROR_CATEGORY_MASK;
30        let code = ((code as u64) << bindings::ERROR_CODE_SHIFT) & bindings::ERROR_CODE_MASK;
31        Self(cat | code)
32    }
33
34    pub fn error(&self) -> TwzError {
35        match self.category() {
36            ErrorCategory::Uncategorized => TwzError::Uncategorized(self.code()),
37            ErrorCategory::Generic => GenericError::twz_error_from_code(self.code()),
38            ErrorCategory::Argument => ArgumentError::twz_error_from_code(self.code()),
39            ErrorCategory::Resource => ResourceError::twz_error_from_code(self.code()),
40            ErrorCategory::Naming => NamingError::twz_error_from_code(self.code()),
41            ErrorCategory::Object => ObjectError::twz_error_from_code(self.code()),
42            ErrorCategory::Io => IoError::twz_error_from_code(self.code()),
43            ErrorCategory::Security => SecurityError::twz_error_from_code(self.code()),
44        }
45    }
46
47    pub fn new(raw: bindings::twz_error) -> Self {
48        Self(raw)
49    }
50
51    pub fn is_success(&self) -> bool {
52        self.code() == bindings::SUCCESS
53    }
54
55    pub fn raw(&self) -> bindings::twz_error {
56        self.0
57    }
58
59    pub fn success() -> Self {
60        Self(bindings::SUCCESS as u64)
61    }
62
63    pub fn result(&self) -> Result<(), TwzError> {
64        if self.is_success() {
65            Ok(())
66        } else {
67            Err(self.error())
68        }
69    }
70}
71
72impl From<TwzError> for RawTwzError {
73    fn from(value: TwzError) -> Self {
74        RawTwzError(value.raw())
75    }
76}
77
78#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
79pub enum TwzError {
80    Uncategorized(u16),
81    Generic(GenericError),
82    Argument(ArgumentError),
83    Resource(ResourceError),
84    Object(ObjectError),
85    Naming(NamingError),
86    Io(IoError),
87    Security(SecurityError),
88}
89
90impl TwzError {
91    pub const NOT_SUPPORTED: Self = Self::Generic(GenericError::NotSupported);
92    pub const TIMED_OUT: Self = Self::Generic(GenericError::TimedOut);
93    pub const WOULD_BLOCK: Self = Self::Generic(GenericError::WouldBlock);
94    pub const INVALID_ARGUMENT: Self = Self::Argument(ArgumentError::InvalidArgument);
95    pub const NOT_FOUND: Self = Self::Naming(NamingError::NotFound);
96    pub const SUCCESS: Self = Self::Uncategorized(bindings::SUCCESS);
97    pub const BAD_HANDLE: Self = Self::Argument(ArgumentError::BadHandle);
98
99    pub fn category(&self) -> ErrorCategory {
100        match self {
101            TwzError::Uncategorized(_) => ErrorCategory::Uncategorized,
102            TwzError::Generic(_) => ErrorCategory::Generic,
103            TwzError::Argument(_) => ErrorCategory::Argument,
104            TwzError::Resource(_) => ErrorCategory::Resource,
105            TwzError::Object(_) => ErrorCategory::Object,
106            TwzError::Io(_) => ErrorCategory::Io,
107            TwzError::Naming(_) => ErrorCategory::Naming,
108            TwzError::Security(_) => ErrorCategory::Security,
109        }
110    }
111
112    pub fn raw(&self) -> bindings::twz_error {
113        let cat = self.category().raw();
114        let code = self.code();
115        RawTwzError::from_parts(cat, code).raw()
116    }
117
118    pub fn code(&self) -> u16 {
119        match self {
120            TwzError::Uncategorized(code) => *code,
121            TwzError::Generic(generic_error) => generic_error.code(),
122            TwzError::Argument(argument_error) => argument_error.code(),
123            TwzError::Resource(resource_error) => resource_error.code(),
124            TwzError::Object(object_error) => object_error.code(),
125            TwzError::Io(io_error) => io_error.code(),
126            TwzError::Naming(naming_error) => naming_error.code(),
127            TwzError::Security(security_error) => security_error.code(),
128        }
129    }
130}
131
132impl Display for TwzError {
133    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
134        match self {
135            TwzError::Uncategorized(code) => write!(f, "uncategorized error: {}", code),
136            TwzError::Generic(generic_error) => write!(f, "generic error: {}", generic_error),
137            TwzError::Argument(argument_error) => write!(f, "argument error: {}", argument_error),
138            TwzError::Resource(resource_error) => write!(f, "resource error: {}", resource_error),
139            TwzError::Object(object_error) => write!(f, "object error: {}", object_error),
140            TwzError::Io(io_error) => write!(f, "I/O error: {}", io_error),
141            TwzError::Naming(naming_error) => write!(f, "naming error: {}", naming_error),
142            TwzError::Security(security_error) => write!(f, "security error: {}", security_error),
143        }
144    }
145}
146
147impl core::error::Error for TwzError {}
148
149impl Into<u64> for TwzError {
150    fn into(self) -> u64 {
151        self.raw()
152    }
153}
154
155#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
156#[repr(u16)]
157pub enum ErrorCategory {
158    Uncategorized = bindings::UNCATEGORIZED_ERROR,
159    Generic = bindings::GENERIC_ERROR,
160    Argument = bindings::ARGUMENT_ERROR,
161    Resource = bindings::RESOURCE_ERROR,
162    Naming = bindings::NAMING_ERROR,
163    Object = bindings::OBJECT_ERROR,
164    Io = bindings::IO_ERROR,
165    Security = bindings::SECURITY_ERROR,
166}
167
168impl Display for ErrorCategory {
169    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
170        match self {
171            ErrorCategory::Uncategorized => write!(f, "uncategorized"),
172            ErrorCategory::Generic => write!(f, "generic"),
173            ErrorCategory::Argument => write!(f, "argument"),
174            ErrorCategory::Resource => write!(f, "resource"),
175            ErrorCategory::Naming => write!(f, "naming"),
176            ErrorCategory::Object => write!(f, "object"),
177            ErrorCategory::Io => write!(f, "I/O"),
178            ErrorCategory::Security => write!(f, "security"),
179        }
180    }
181}
182
183impl core::error::Error for ErrorCategory {}
184
185impl ErrorCategory {
186    pub fn raw(&self) -> u16 {
187        *self as u16
188    }
189}
190
191#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
192#[repr(u16)]
193pub enum GenericError {
194    Other = bindings::OTHER_ERROR,
195    NotSupported = bindings::NOT_SUPPORTED,
196    Internal = bindings::INTERNAL,
197    WouldBlock = bindings::WOULD_BLOCK,
198    TimedOut = bindings::TIMED_OUT,
199    AccessDenied = bindings::ACCESS_DENIED,
200    NoSuchOperation = bindings::NO_SUCH_OPERATION,
201    Interrupted = bindings::INTERRUPTED,
202    InProgress = bindings::IN_PROGRESS,
203}
204
205impl GenericError {
206    fn twz_error_from_code(code: u16) -> TwzError {
207        match code {
208            bindings::NOT_SUPPORTED => TwzError::Generic(GenericError::NotSupported),
209            bindings::INTERNAL => TwzError::Generic(GenericError::Internal),
210            bindings::WOULD_BLOCK => TwzError::Generic(GenericError::WouldBlock),
211            bindings::TIMED_OUT => TwzError::Generic(GenericError::TimedOut),
212            bindings::NO_SUCH_OPERATION => TwzError::Generic(GenericError::NoSuchOperation),
213            _ => TwzError::Uncategorized(code),
214        }
215    }
216
217    fn code(&self) -> u16 {
218        *self as u16
219    }
220}
221
222impl Display for GenericError {
223    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
224        match self {
225            GenericError::NotSupported => write!(f, "not supported"),
226            GenericError::Internal => write!(f, "internal"),
227            GenericError::WouldBlock => write!(f, "would block"),
228            GenericError::TimedOut => write!(f, "timed out"),
229            GenericError::AccessDenied => write!(f, "access denied"),
230            GenericError::NoSuchOperation => write!(f, "no such operation"),
231            GenericError::Interrupted => write!(f, "interrupted"),
232            GenericError::InProgress => write!(f, "in-progress"),
233            GenericError::Other => write!(f, "other"),
234        }
235    }
236}
237
238impl core::error::Error for GenericError {}
239
240impl From<GenericError> for TwzError {
241    fn from(value: GenericError) -> Self {
242        Self::Generic(value)
243    }
244}
245
246#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
247#[repr(u16)]
248pub enum ArgumentError {
249    InvalidArgument = bindings::INVALID_ARGUMENT,
250    WrongType = bindings::WRONG_TYPE,
251    InvalidAddress = bindings::INVALID_ADDRESS,
252    BadHandle = bindings::BAD_HANDLE,
253}
254
255impl ArgumentError {
256    fn twz_error_from_code(code: u16) -> TwzError {
257        match code {
258            bindings::INVALID_ARGUMENT => TwzError::Argument(ArgumentError::InvalidArgument),
259            bindings::WRONG_TYPE => TwzError::Argument(ArgumentError::WrongType),
260            bindings::INVALID_ADDRESS => TwzError::Argument(ArgumentError::InvalidAddress),
261            bindings::BAD_HANDLE => TwzError::Argument(ArgumentError::BadHandle),
262            _ => TwzError::Uncategorized(code),
263        }
264    }
265
266    fn code(&self) -> u16 {
267        *self as u16
268    }
269}
270
271impl Display for ArgumentError {
272    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
273        match self {
274            ArgumentError::InvalidArgument => write!(f, "invalid argument"),
275            ArgumentError::WrongType => write!(f, "wrong type"),
276            ArgumentError::InvalidAddress => write!(f, "invalid address"),
277            ArgumentError::BadHandle => write!(f, "bad handle"),
278        }
279    }
280}
281
282impl core::error::Error for ArgumentError {}
283
284impl From<ArgumentError> for TwzError {
285    fn from(value: ArgumentError) -> Self {
286        Self::Argument(value)
287    }
288}
289
290#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
291#[repr(u16)]
292pub enum ResourceError {
293    OutOfMemory = bindings::OUT_OF_MEMORY,
294    OutOfResources = bindings::OUT_OF_RESOURCES,
295    OutOfNames = bindings::OUT_OF_NAMES,
296    Unavailable = bindings::UNAVAILABLE,
297    Refused = bindings::REFUSED,
298    Busy = bindings::BUSY,
299    NotConnected = bindings::NOT_CONNECTED,
300    Unreachable = bindings::UNREACHABLE,
301    NonAtomic = bindings::NON_ATOMIC,
302}
303
304impl ResourceError {
305    fn twz_error_from_code(code: u16) -> TwzError {
306        match code {
307            bindings::OUT_OF_MEMORY => TwzError::Resource(ResourceError::OutOfMemory),
308            bindings::OUT_OF_RESOURCES => TwzError::Resource(ResourceError::OutOfResources),
309            bindings::OUT_OF_NAMES => TwzError::Resource(ResourceError::OutOfNames),
310            bindings::UNAVAILABLE => TwzError::Resource(ResourceError::Unavailable),
311            _ => TwzError::Uncategorized(code),
312        }
313    }
314
315    fn code(&self) -> u16 {
316        *self as u16
317    }
318}
319
320impl Display for ResourceError {
321    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
322        match self {
323            ResourceError::OutOfMemory => write!(f, "out of memory"),
324            ResourceError::OutOfResources => write!(f, "out of resources"),
325            ResourceError::OutOfNames => write!(f, "out of names"),
326            ResourceError::Unavailable => write!(f, "unavailable"),
327            ResourceError::Refused => write!(f, "refused"),
328            ResourceError::Busy => write!(f, "busy"),
329            ResourceError::NotConnected => write!(f, "not connected"),
330            ResourceError::Unreachable => write!(f, "unreachable"),
331            ResourceError::NonAtomic => write!(f, "non-atomic"),
332        }
333    }
334}
335
336impl core::error::Error for ResourceError {}
337
338impl From<ResourceError> for TwzError {
339    fn from(value: ResourceError) -> Self {
340        Self::Resource(value)
341    }
342}
343
344#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
345#[repr(u16)]
346pub enum ObjectError {
347    MapFailed = bindings::MAPPING_FAILED,
348    NotMapped = bindings::NOT_MAPPED,
349    InvalidFote = bindings::INVALID_FOTE,
350    InvalidPtr = bindings::INVALID_PTR,
351    InvalidMeta = bindings::INVALID_META,
352    BaseTypeMismatch = bindings::BASETYPE_MISMATCH,
353    NoSuchObject = bindings::NO_SUCH_OBJECT,
354}
355
356impl ObjectError {
357    fn twz_error_from_code(code: u16) -> TwzError {
358        match code {
359            bindings::MAPPING_FAILED => TwzError::Object(ObjectError::MapFailed),
360            bindings::NOT_MAPPED => TwzError::Object(ObjectError::NotMapped),
361            bindings::INVALID_FOTE => TwzError::Object(ObjectError::InvalidFote),
362            bindings::INVALID_PTR => TwzError::Object(ObjectError::InvalidPtr),
363            bindings::INVALID_META => TwzError::Object(ObjectError::InvalidMeta),
364            bindings::BASETYPE_MISMATCH => TwzError::Object(ObjectError::BaseTypeMismatch),
365            bindings::NO_SUCH_OBJECT => TwzError::Object(ObjectError::NoSuchObject),
366            _ => TwzError::Uncategorized(code),
367        }
368    }
369
370    fn code(&self) -> u16 {
371        *self as u16
372    }
373}
374
375impl Display for ObjectError {
376    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
377        match self {
378            ObjectError::MapFailed => write!(f, "mapping failed"),
379            ObjectError::NotMapped => write!(f, "not mapped"),
380            ObjectError::InvalidFote => write!(f, "invalid FOT entry"),
381            ObjectError::InvalidPtr => write!(f, "invalid pointer"),
382            ObjectError::InvalidMeta => write!(f, "invalid metadata"),
383            ObjectError::BaseTypeMismatch => write!(f, "base type mismatch"),
384            ObjectError::NoSuchObject => write!(f, "no such object"),
385        }
386    }
387}
388
389impl core::error::Error for ObjectError {}
390
391impl From<ObjectError> for TwzError {
392    fn from(value: ObjectError) -> Self {
393        Self::Object(value)
394    }
395}
396
397#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
398#[repr(u16)]
399pub enum IoError {
400    Other = bindings::OTHER_IO_ERROR,
401    DataLoss = bindings::DATA_LOSS,
402    DeviceError = bindings::DEVICE_ERROR,
403    SeekFailed = bindings::SEEK_FAILED,
404    Reset = bindings::RESET,
405}
406
407impl IoError {
408    fn twz_error_from_code(code: u16) -> TwzError {
409        match code {
410            bindings::OTHER_IO_ERROR => TwzError::Io(IoError::Other),
411            bindings::DATA_LOSS => TwzError::Io(IoError::DataLoss),
412            bindings::DEVICE_ERROR => TwzError::Io(IoError::DeviceError),
413            bindings::SEEK_FAILED => TwzError::Io(IoError::SeekFailed),
414            _ => TwzError::Uncategorized(code),
415        }
416    }
417
418    fn code(&self) -> u16 {
419        *self as u16
420    }
421}
422
423impl Display for IoError {
424    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
425        match self {
426            IoError::Other => write!(f, "other I/O error"),
427            IoError::DataLoss => write!(f, "data loss"),
428            IoError::DeviceError => write!(f, "device error"),
429            IoError::SeekFailed => write!(f, "seek failed"),
430            IoError::Reset => write!(f, "reset"),
431        }
432    }
433}
434
435impl core::error::Error for IoError {}
436
437impl From<IoError> for TwzError {
438    fn from(value: IoError) -> Self {
439        Self::Io(value)
440    }
441}
442
443#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
444#[repr(u16)]
445pub enum NamingError {
446    NotFound = bindings::NOT_FOUND,
447    AlreadyExists = bindings::ALREADY_EXISTS,
448    WrongNameKind = bindings::WRONG_NAME_KIND,
449    AlreadyBound = bindings::ALREADY_BOUND,
450    LinkLoop = bindings::LINK_LOOP,
451    NotEmpty = bindings::NOT_EMPTY,
452}
453
454impl NamingError {
455    fn twz_error_from_code(code: u16) -> TwzError {
456        match code {
457            bindings::NOT_FOUND => TwzError::Naming(NamingError::NotFound),
458            bindings::ALREADY_EXISTS => TwzError::Naming(NamingError::AlreadyExists),
459            bindings::WRONG_NAME_KIND => TwzError::Naming(NamingError::WrongNameKind),
460            bindings::ALREADY_BOUND => TwzError::Naming(NamingError::AlreadyBound),
461            bindings::LINK_LOOP => TwzError::Naming(NamingError::LinkLoop),
462            bindings::NOT_EMPTY => TwzError::Naming(NamingError::NotEmpty),
463            _ => TwzError::Uncategorized(code),
464        }
465    }
466
467    fn code(&self) -> u16 {
468        *self as u16
469    }
470}
471
472impl Display for NamingError {
473    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
474        match self {
475            NamingError::NotFound => write!(f, "not found"),
476            NamingError::AlreadyExists => write!(f, "already exists"),
477            NamingError::WrongNameKind => write!(f, "wrong name kind"),
478            NamingError::AlreadyBound => write!(f, "already bound"),
479            NamingError::LinkLoop => write!(f, "link loop"),
480            NamingError::NotEmpty => write!(f, "not empty"),
481        }
482    }
483}
484
485impl core::error::Error for NamingError {}
486
487impl From<NamingError> for TwzError {
488    fn from(value: NamingError) -> Self {
489        Self::Naming(value)
490    }
491}
492
493#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
494#[repr(u16)]
495pub enum SecurityError {
496    InvalidKey = bindings::INVALID_KEY,
497    InvalidScheme = bindings::INVALID_SCHEME,
498    SignatureMismatch = bindings::SIGNATURE_MISMATCH,
499    GateDenied = bindings::GATE_DENIED,
500    InvalidGate = bindings::INVALID_GATE,
501}
502
503impl SecurityError {
504    fn twz_error_from_code(code: u16) -> TwzError {
505        match code {
506            bindings::INVALID_KEY => TwzError::Security(SecurityError::InvalidKey),
507            bindings::INVALID_SCHEME => TwzError::Security(SecurityError::InvalidScheme),
508            bindings::INVALID_GATE => TwzError::Security(SecurityError::InvalidGate),
509            bindings::GATE_DENIED => TwzError::Security(SecurityError::GateDenied),
510            bindings::SIGNATURE_MISMATCH => TwzError::Security(SecurityError::SignatureMismatch),
511            _ => TwzError::Uncategorized(code),
512        }
513    }
514
515    fn code(&self) -> u16 {
516        *self as u16
517    }
518}
519
520impl Display for SecurityError {
521    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
522        match self {
523            SecurityError::InvalidKey => write!(f, "invalid key"),
524            SecurityError::InvalidScheme => write!(f, "invalid scheme"),
525            SecurityError::SignatureMismatch => write!(f, "signature mismatch"),
526            SecurityError::GateDenied => write!(f, "gate denied"),
527            SecurityError::InvalidGate => write!(f, "invalid gate"),
528        }
529    }
530}
531
532impl core::error::Error for SecurityError {}
533
534impl From<SecurityError> for TwzError {
535    fn from(value: SecurityError) -> Self {
536        Self::Security(value)
537    }
538}
539
540impl From<core::alloc::AllocError> for TwzError {
541    fn from(_value: core::alloc::AllocError) -> Self {
542        ResourceError::OutOfMemory.into()
543    }
544}
545
546#[cfg(all(feature = "stderr", not(doc)))]
547extern crate std;
548#[cfg(all(feature = "stderr", not(doc)))]
549impl From<std::io::ErrorKind> for TwzError {
550    fn from(value: std::io::ErrorKind) -> Self {
551        match value {
552            std::io::ErrorKind::NotFound => NamingError::NotFound.into(),
553            std::io::ErrorKind::PermissionDenied => GenericError::AccessDenied.into(),
554            std::io::ErrorKind::ConnectionRefused => ResourceError::Refused.into(),
555            std::io::ErrorKind::ConnectionReset => IoError::Reset.into(),
556            std::io::ErrorKind::HostUnreachable => ResourceError::Unreachable.into(),
557            std::io::ErrorKind::NetworkUnreachable => ResourceError::Unreachable.into(),
558            std::io::ErrorKind::ConnectionAborted => IoError::Reset.into(),
559            std::io::ErrorKind::NotConnected => ResourceError::NotConnected.into(),
560            std::io::ErrorKind::AddrInUse => NamingError::AlreadyBound.into(),
561            std::io::ErrorKind::AddrNotAvailable => NamingError::NotFound.into(),
562            std::io::ErrorKind::NetworkDown => ResourceError::Unavailable.into(),
563            std::io::ErrorKind::BrokenPipe => IoError::Reset.into(),
564            std::io::ErrorKind::AlreadyExists => NamingError::AlreadyExists.into(),
565            std::io::ErrorKind::WouldBlock => GenericError::WouldBlock.into(),
566            std::io::ErrorKind::NotADirectory => NamingError::WrongNameKind.into(),
567            std::io::ErrorKind::IsADirectory => NamingError::WrongNameKind.into(),
568            std::io::ErrorKind::DirectoryNotEmpty => NamingError::NotEmpty.into(),
569            std::io::ErrorKind::ReadOnlyFilesystem => ResourceError::Refused.into(),
570            std::io::ErrorKind::FilesystemLoop => NamingError::LinkLoop.into(),
571            std::io::ErrorKind::StaleNetworkFileHandle => ArgumentError::BadHandle.into(),
572            std::io::ErrorKind::InvalidInput => ArgumentError::InvalidArgument.into(),
573            std::io::ErrorKind::InvalidData => GenericError::Internal.into(),
574            std::io::ErrorKind::TimedOut => GenericError::TimedOut.into(),
575            std::io::ErrorKind::WriteZero => IoError::DataLoss.into(),
576            std::io::ErrorKind::StorageFull => ResourceError::OutOfResources.into(),
577            std::io::ErrorKind::NotSeekable => IoError::SeekFailed.into(),
578            std::io::ErrorKind::QuotaExceeded => ResourceError::OutOfResources.into(),
579            std::io::ErrorKind::FileTooLarge => ResourceError::OutOfResources.into(),
580            std::io::ErrorKind::ResourceBusy => ResourceError::Busy.into(),
581            std::io::ErrorKind::ExecutableFileBusy => ResourceError::Busy.into(),
582            std::io::ErrorKind::Deadlock => ResourceError::Busy.into(),
583            std::io::ErrorKind::CrossesDevices => ArgumentError::InvalidArgument.into(),
584            std::io::ErrorKind::TooManyLinks => NamingError::LinkLoop.into(),
585            std::io::ErrorKind::InvalidFilename => ArgumentError::InvalidArgument.into(),
586            std::io::ErrorKind::ArgumentListTooLong => ArgumentError::InvalidArgument.into(),
587            std::io::ErrorKind::Interrupted => GenericError::Interrupted.into(),
588            std::io::ErrorKind::Unsupported => GenericError::NotSupported.into(),
589            std::io::ErrorKind::UnexpectedEof => IoError::Reset.into(),
590            std::io::ErrorKind::OutOfMemory => ResourceError::OutOfMemory.into(),
591            std::io::ErrorKind::InProgress => GenericError::InProgress.into(),
592            _ => GenericError::Other.into(),
593        }
594    }
595}
596
597#[cfg(all(feature = "stderr", not(doc)))]
598impl From<std::io::Error> for TwzError {
599    fn from(value: std::io::Error) -> Self {
600        value.kind().into()
601    }
602}
603
604#[cfg(all(feature = "stderr", not(doc)))]
605impl From<TwzError> for std::io::Error {
606    fn from(value: TwzError) -> Self {
607        std::io::Error::new(std::io::ErrorKind::Other, value)
608    }
609}