Skip to main content

network/
error.rs

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