1use core::{fmt::Display, num::NonZeroU8};
2use internationalization::translate;
3use smoltcp::socket::{dns, icmp, udp};
4
5pub type Result<T> = core::result::Result<T, Error>;
6
7#[derive(Debug, Copy, Clone, PartialEq, Eq)]
8#[repr(u8)]
9pub enum Error {
10 NotFound = 1,
11 PermissionDenied,
12 ConnectionRefused,
13 ConnectionReset,
14 HostUnreachable,
15 NetworkUnreachable,
16 ConnectionAborted,
17 NotConnected,
18 AddressInUse,
19 AddressNotAvailable,
20 NetworkDown,
21 BrokenPipe,
22 AlreadyExists,
23 WouldBlock,
24 InvalidInput,
25 InvalidData,
26 TimedOut,
27 WriteZero,
28 StorageFull,
29 ResourceBusy,
30 Deadlock,
31 Interrupted,
32 Unsupported,
33 UnexpectedEndOfFile,
34 OutOfMemory,
35 Pending,
36 UnsupportedProtocol,
37 InvalidIdentifier,
38 DuplicateIdentifier,
39 FailedToGenerateSeed(file_system::Error),
40 FailedToSpawnNetworkTask(task::Error),
41 InvalidName,
43 NameTooLong,
44 Failed,
45 InvalidState,
47 InvalidPort,
48 NoRoute,
49 Truncated,
51 SocketNotBound,
52 PacketTooLarge,
53 InvalidEndpoint,
54
55 FailedToMountDevice(virtual_file_system::Error),
56
57 NoFreeSlot,
58
59 Other,
60}
61
62impl core::error::Error for Error {}
63
64impl Error {
65 pub const fn get_discriminant(&self) -> NonZeroU8 {
66 unsafe { *(self as *const Self as *const NonZeroU8) }
67 }
68}
69
70impl From<Error> for NonZeroU8 {
71 fn from(value: Error) -> Self {
72 value.get_discriminant()
73 }
74}
75
76impl Display for Error {
77 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
78 match self {
79 Error::NotFound => write!(f, translate!("Not found")),
80 Error::PermissionDenied => write!(f, translate!("Permission denied")),
81 Error::ConnectionRefused => write!(f, translate!("Connection refused")),
82 Error::ConnectionReset => write!(f, translate!("Connection reset")),
83 Error::HostUnreachable => write!(f, translate!("Host unreachable")),
84 Error::NetworkUnreachable => write!(f, translate!("Network unreachable")),
85 Error::ConnectionAborted => write!(f, translate!("Connection aborted")),
86 Error::NotConnected => write!(f, translate!("Not connected")),
87 Error::AddressInUse => write!(f, translate!("Address in use")),
88 Error::AddressNotAvailable => write!(f, translate!("Address not available")),
89 Error::NetworkDown => write!(f, translate!("Network down")),
90 Error::BrokenPipe => write!(f, translate!("Broken pipe")),
91 Error::AlreadyExists => write!(f, translate!("Already exists")),
92 Error::WouldBlock => write!(f, translate!("Would block")),
93 Error::InvalidInput => write!(f, translate!("Invalid input")),
94 Error::InvalidData => write!(f, translate!("Invalid data")),
95 Error::TimedOut => write!(f, translate!("Timed out")),
96 Error::WriteZero => write!(f, translate!("Write zero")),
97 Error::StorageFull => write!(f, translate!("Storage full")),
98 Error::ResourceBusy => write!(f, translate!("Resource busy")),
99 Error::Deadlock => write!(f, translate!("Deadlock")),
100 Error::Interrupted => write!(f, translate!("Interrupted")),
101 Error::Unsupported => write!(f, translate!("Unsupported operation")),
102 Error::UnexpectedEndOfFile => write!(f, translate!("Unexpected end of file")),
103 Error::OutOfMemory => write!(f, translate!("Out of memory")),
104 Error::Pending => write!(f, translate!("In progress operation not completed yet")),
105 Error::UnsupportedProtocol => {
106 write!(f, translate!("Unsupported protocol used in operation"))
107 }
108 Error::InvalidIdentifier => {
109 write!(f, translate!("Invalid identifier provided for operation"))
110 }
111 Error::DuplicateIdentifier => {
112 write!(f, translate!("Duplicate identifier found in operation"))
113 }
114 Error::FailedToGenerateSeed(e) => {
115 write!(f, translate!("Failed to generate seed: {}"), e)
116 }
117 Error::FailedToSpawnNetworkTask(e) => {
118 write!(f, translate!("Failed to spawn network task: {}"), e)
119 }
120 Error::InvalidName => write!(f, translate!("Invalid name")),
121 Error::NameTooLong => write!(f, translate!("Name too long")),
122 Error::Failed => write!(f, translate!("Failed")),
123 Error::InvalidState => write!(f, translate!("Invalid state for operation")),
124 Error::InvalidPort => write!(f, translate!("Invalid port specified")),
125 Error::NoRoute => write!(f, translate!("No route to host")),
126 Error::Truncated => write!(f, translate!("Truncated packet received")),
127 Error::SocketNotBound => write!(f, translate!("Socket not bound")),
128 Error::PacketTooLarge => write!(f, translate!("Packet too large to send")),
129 Error::InvalidEndpoint => write!(f, translate!("Invalid endpoint specified")),
130 Error::FailedToMountDevice(e) => {
131 write!(f, translate!("Failed to mount device: {}"), e)
132 }
133 Error::NoFreeSlot => write!(f, translate!("No free slot available")),
134 Error::Other => write!(f, translate!("Other error occurred")),
135 }
136 }
137}
138
139impl From<dns::StartQueryError> for Error {
140 fn from(e: dns::StartQueryError) -> Self {
141 match e {
142 dns::StartQueryError::InvalidName => Error::InvalidName,
143 dns::StartQueryError::NameTooLong => Error::NameTooLong,
144 dns::StartQueryError::NoFreeSlot => Error::NoFreeSlot,
145 }
146 }
147}
148
149impl From<dns::GetQueryResultError> for Error {
150 fn from(e: dns::GetQueryResultError) -> Self {
151 match e {
152 dns::GetQueryResultError::Pending => Error::Pending,
153 dns::GetQueryResultError::Failed => Error::Failed,
154 }
155 }
156}
157
158impl From<icmp::SendError> for Error {
159 fn from(e: icmp::SendError) -> Self {
160 match e {
161 icmp::SendError::Unaddressable => Error::InvalidEndpoint,
162 icmp::SendError::BufferFull => Error::ResourceBusy,
163 }
164 }
165}
166
167impl From<icmp::BindError> for Error {
168 fn from(e: icmp::BindError) -> Self {
169 match e {
170 icmp::BindError::InvalidState => Error::InvalidState,
171 icmp::BindError::Unaddressable => Error::NoRoute,
172 }
173 }
174}
175
176impl From<udp::BindError> for Error {
177 fn from(e: udp::BindError) -> Self {
178 match e {
179 udp::BindError::InvalidState => Error::InvalidState,
180 udp::BindError::Unaddressable => Error::NoRoute,
181 }
182 }
183}