network/
error.rs

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    // - DNS
41    InvalidName,
42    NameTooLong,
43    Failed,
44    // - Accept / Connect
45    InvalidState,
46    InvalidPort,
47    NoRoute,
48    // Udp
49    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}