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