1#![no_std]
8
9use core::fmt;
10use zx_types as sys;
11
12#[macro_export]
18macro_rules! assoc_values {
19 ($typename:ident, [$($(#[$attr:meta])* $name:ident = $value:path;)*]) => {
20 #[allow(non_upper_case_globals)]
21 impl $typename {
22 $(
23 $(#[$attr])*
24 pub const $name: $typename = $typename($value);
25 )*
26
27 fn assoc_const_name(&self) -> Option<&'static str> {
28 match self.0 {
29 $(
30 $value => Some(stringify!($name)),
31 )*
32 _ => None,
33 }
34 }
35 }
36
37 impl ::core::fmt::Debug for $typename {
38 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
39 f.write_str(concat!(stringify!($typename), "("))?;
40 match self.assoc_const_name() {
41 Some(name) => f.write_str(&name)?,
42 None => ::core::fmt::Debug::fmt(&self.0, f)?,
43 }
44 f.write_str(")")
45 }
46 }
47 }
48}
49
50#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
57#[repr(transparent)]
58pub struct Status(sys::zx_status_t);
59impl Status {
60 pub fn ok(raw: sys::zx_status_t) -> Result<(), Status> {
63 if raw == Status::OK.0 { Ok(()) } else { Err(Status(raw)) }
64 }
65
66 #[inline]
70 pub const fn result_into_raw(res: Result<(), Self>) -> sys::zx_status_t {
71 match res {
72 Ok(()) => sys::ZX_OK,
73 Err(status) => status.0,
74 }
75 }
76
77 #[inline]
79 pub const fn try_from_raw(raw: sys::zx_status_t) -> Option<Self> {
80 if raw == sys::ZX_OK { None } else { Some(Status(raw)) }
81 }
82
83 #[inline]
90 #[doc(hidden)]
91 pub const fn from_raw(raw: sys::zx_status_t) -> Self {
92 Status(raw)
93 }
94
95 pub fn into_raw(self) -> sys::zx_status_t {
96 self.0
97 }
98}
99
100pub fn ok(raw: sys::zx_status_t) -> Result<(), Status> {
102 Status::ok(raw)
103}
104
105assoc_values!(Status, [
107 #[doc = "Indicates an operation was successful."]
108 OK = sys::ZX_OK;
109 #[doc = "The system encountered an otherwise unspecified error while performing the"]
110 #[doc = "operation."]
111 INTERNAL = sys::ZX_ERR_INTERNAL;
112 #[doc = "The operation is not implemented, supported, or enabled."]
113 NOT_SUPPORTED = sys::ZX_ERR_NOT_SUPPORTED;
114 #[doc = "The system was not able to allocate some resource needed for the operation."]
115 NO_RESOURCES = sys::ZX_ERR_NO_RESOURCES;
116 #[doc = "The system was not able to allocate memory needed for the operation."]
117 NO_MEMORY = sys::ZX_ERR_NO_MEMORY;
118 #[doc = "The system call was interrupted, but should be retried. This should not be"]
119 #[doc = "seen outside of the VDSO."]
120 INTERRUPTED_RETRY = sys::ZX_ERR_INTERRUPTED_RETRY;
121 #[doc = "An argument is invalid. For example, a null pointer when a null pointer is"]
122 #[doc = "not permitted."]
123 INVALID_ARGS = sys::ZX_ERR_INVALID_ARGS;
124 #[doc = "A specified handle value does not refer to a handle."]
125 BAD_HANDLE = sys::ZX_ERR_BAD_HANDLE;
126 #[doc = "The subject of the operation is the wrong type to perform the operation."]
127 #[doc = ""]
128 #[doc = "For example: Attempting a message_read on a thread handle."]
129 WRONG_TYPE = sys::ZX_ERR_WRONG_TYPE;
130 #[doc = "The specified syscall number is invalid."]
131 BAD_SYSCALL = sys::ZX_ERR_BAD_SYSCALL;
132 #[doc = "An argument is outside the valid range for this operation."]
133 OUT_OF_RANGE = sys::ZX_ERR_OUT_OF_RANGE;
134 #[doc = "The caller-provided buffer is too small for this operation."]
135 BUFFER_TOO_SMALL = sys::ZX_ERR_BUFFER_TOO_SMALL;
136 #[doc = "The operation failed because the current state of the object does not allow"]
137 #[doc = "it, or a precondition of the operation is not satisfied."]
138 BAD_STATE = sys::ZX_ERR_BAD_STATE;
139 #[doc = "The time limit for the operation elapsed before the operation completed."]
140 TIMED_OUT = sys::ZX_ERR_TIMED_OUT;
141 #[doc = "The operation cannot be performed currently but potentially could succeed if"]
142 #[doc = "the caller waits for a prerequisite to be satisfied, like waiting for a"]
143 #[doc = "handle to be readable or writable."]
144 #[doc = ""]
145 #[doc = "Example: Attempting to read from a channel that has no messages waiting but"]
146 #[doc = "has an open remote will return `ZX_ERR_SHOULD_WAIT`. In contrast, attempting"]
147 #[doc = "to read from a channel that has no messages waiting and has a closed remote"]
148 #[doc = "end will return `ZX_ERR_PEER_CLOSED`."]
149 SHOULD_WAIT = sys::ZX_ERR_SHOULD_WAIT;
150 #[doc = "The in-progress operation, for example, a wait, has been canceled."]
151 CANCELED = sys::ZX_ERR_CANCELED;
152 #[doc = "The operation failed because the remote end of the subject of the operation"]
153 #[doc = "was closed."]
154 PEER_CLOSED = sys::ZX_ERR_PEER_CLOSED;
155 #[doc = "The requested entity is not found."]
156 NOT_FOUND = sys::ZX_ERR_NOT_FOUND;
157 #[doc = "An object with the specified identifier already exists."]
158 #[doc = ""]
159 #[doc = "Example: Attempting to create a file when a file already exists with that"]
160 #[doc = "name."]
161 ALREADY_EXISTS = sys::ZX_ERR_ALREADY_EXISTS;
162 #[doc = "The operation failed because the named entity is already owned or controlled"]
163 #[doc = "by another entity. The operation could succeed later if the current owner"]
164 #[doc = "releases the entity."]
165 ALREADY_BOUND = sys::ZX_ERR_ALREADY_BOUND;
166 #[doc = "The subject of the operation is currently unable to perform the operation."]
167 #[doc = ""]
168 #[doc = "This is used when there's no direct way for the caller to observe when the"]
169 #[doc = "subject will be able to perform the operation and should thus retry."]
170 UNAVAILABLE = sys::ZX_ERR_UNAVAILABLE;
171 #[doc = "The caller did not have permission to perform the specified operation."]
172 ACCESS_DENIED = sys::ZX_ERR_ACCESS_DENIED;
173 #[doc = "Otherwise-unspecified error occurred during I/O."]
174 IO = sys::ZX_ERR_IO;
175 #[doc = "The entity the I/O operation is being performed on rejected the operation."]
176 #[doc = ""]
177 #[doc = "Example: an I2C device NAK'ing a transaction or a disk controller rejecting"]
178 #[doc = "an invalid command, or a stalled USB endpoint."]
179 IO_REFUSED = sys::ZX_ERR_IO_REFUSED;
180 #[doc = "The data in the operation failed an integrity check and is possibly"]
181 #[doc = "corrupted."]
182 #[doc = ""]
183 #[doc = "Example: CRC or Parity error."]
184 IO_DATA_INTEGRITY = sys::ZX_ERR_IO_DATA_INTEGRITY;
185 #[doc = "The data in the operation is currently unavailable and may be permanently"]
186 #[doc = "lost."]
187 #[doc = ""]
188 #[doc = "Example: A disk block is irrecoverably damaged."]
189 IO_DATA_LOSS = sys::ZX_ERR_IO_DATA_LOSS;
190 #[doc = "The device is no longer available (has been unplugged from the system,"]
191 #[doc = "powered down, or the driver has been unloaded)."]
192 IO_NOT_PRESENT = sys::ZX_ERR_IO_NOT_PRESENT;
193 #[doc = "More data was received from the device than expected."]
194 #[doc = ""]
195 #[doc = "Example: a USB \"babble\" error due to a device sending more data than the"]
196 #[doc = "host queued to receive."]
197 IO_OVERRUN = sys::ZX_ERR_IO_OVERRUN;
198 #[doc = "An operation did not complete within the required timeframe."]
199 #[doc = ""]
200 #[doc = "Example: A USB isochronous transfer that failed to complete due to an"]
201 #[doc = "overrun or underrun."]
202 IO_MISSED_DEADLINE = sys::ZX_ERR_IO_MISSED_DEADLINE;
203 #[doc = "The data in the operation is invalid parameter or is out of range."]
204 #[doc = ""]
205 #[doc = "Example: A USB transfer that failed to complete with TRB Error"]
206 IO_INVALID = sys::ZX_ERR_IO_INVALID;
207 #[doc = "Path name is too long."]
208 BAD_PATH = sys::ZX_ERR_BAD_PATH;
209 #[doc = "The object is not a directory or does not support directory operations."]
210 #[doc = ""]
211 #[doc = "Example: Attempted to open a file as a directory or attempted to do"]
212 #[doc = "directory operations on a file."]
213 NOT_DIR = sys::ZX_ERR_NOT_DIR;
214 #[doc = "Object is not a regular file."]
215 NOT_FILE = sys::ZX_ERR_NOT_FILE;
216 #[doc = "This operation would cause a file to exceed a filesystem-specific size"]
217 #[doc = "limit."]
218 FILE_BIG = sys::ZX_ERR_FILE_BIG;
219 #[doc = "The filesystem or device space is exhausted."]
220 NO_SPACE = sys::ZX_ERR_NO_SPACE;
221 #[doc = "The directory is not empty for an operation that requires it to be empty."]
222 #[doc = ""]
223 #[doc = "For example, non-recursively deleting a directory with files still in it."]
224 NOT_EMPTY = sys::ZX_ERR_NOT_EMPTY;
225 #[doc = "An indicate to not call again."]
226 #[doc = ""]
227 #[doc = "The flow control values `ZX_ERR_STOP`, `ZX_ERR_NEXT`, and `ZX_ERR_ASYNC` are"]
228 #[doc = "not errors and will never be returned by a system call or public API. They"]
229 #[doc = "allow callbacks to request their caller perform some other operation."]
230 #[doc = ""]
231 #[doc = "For example, a callback might be called on every event until it returns"]
232 #[doc = "something other than `ZX_OK`. This status allows differentiation between"]
233 #[doc = "\"stop due to an error\" and \"stop because work is done.\""]
234 STOP = sys::ZX_ERR_STOP;
235 #[doc = "Advance to the next item."]
236 #[doc = ""]
237 #[doc = "The flow control values `ZX_ERR_STOP`, `ZX_ERR_NEXT`, and `ZX_ERR_ASYNC` are"]
238 #[doc = "not errors and will never be returned by a system call or public API. They"]
239 #[doc = "allow callbacks to request their caller perform some other operation."]
240 #[doc = ""]
241 #[doc = "For example, a callback could use this value to indicate it did not consume"]
242 #[doc = "an item passed to it, but by choice, not due to an error condition."]
243 NEXT = sys::ZX_ERR_NEXT;
244 #[doc = "Ownership of the item has moved to an asynchronous worker."]
245 #[doc = ""]
246 #[doc = "The flow control values `ZX_ERR_STOP`, `ZX_ERR_NEXT`, and `ZX_ERR_ASYNC` are"]
247 #[doc = "not errors and will never be returned by a system call or public API. They"]
248 #[doc = "allow callbacks to request their caller perform some other operation."]
249 #[doc = ""]
250 #[doc = "Unlike `ZX_ERR_STOP`, which implies that iteration on an object"]
251 #[doc = "should stop, and `ZX_ERR_NEXT`, which implies that iteration"]
252 #[doc = "should continue to the next item, `ZX_ERR_ASYNC` implies"]
253 #[doc = "that an asynchronous worker is responsible for continuing iteration."]
254 #[doc = ""]
255 #[doc = "For example, a callback will be called on every event, but one event needs"]
256 #[doc = "to handle some work asynchronously before it can continue. `ZX_ERR_ASYNC`"]
257 #[doc = "implies the worker is responsible for resuming iteration once its work has"]
258 #[doc = "completed."]
259 ASYNC = sys::ZX_ERR_ASYNC;
260 #[doc = "The specified protocol is not supported."]
261 PROTOCOL_NOT_SUPPORTED = sys::ZX_ERR_PROTOCOL_NOT_SUPPORTED;
262 #[doc = "The host is unreachable."]
263 ADDRESS_UNREACHABLE = sys::ZX_ERR_ADDRESS_UNREACHABLE;
264 #[doc = "Address is being used by someone else."]
265 ADDRESS_IN_USE = sys::ZX_ERR_ADDRESS_IN_USE;
266 #[doc = "The socket is not connected."]
267 NOT_CONNECTED = sys::ZX_ERR_NOT_CONNECTED;
268 #[doc = "The remote peer rejected the connection."]
269 CONNECTION_REFUSED = sys::ZX_ERR_CONNECTION_REFUSED;
270 #[doc = "The connection was reset."]
271 CONNECTION_RESET = sys::ZX_ERR_CONNECTION_RESET;
272 #[doc = "The connection was aborted."]
273 CONNECTION_ABORTED = sys::ZX_ERR_CONNECTION_ABORTED;
274]);
275impl Status {
278 pub fn from_result(res: Result<(), Self>) -> Self {
279 res.into()
280 }
281}
282
283impl fmt::Display for Status {
284 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
285 match self.assoc_const_name() {
286 Some(name) => name.fmt(f),
287 None => write!(f, "Unknown zircon status code: {}", self.0),
288 }
289 }
290}
291
292impl core::error::Error for Status {}
293
294impl From<Result<(), Status>> for Status {
295 fn from(res: Result<(), Status>) -> Status {
296 match res {
297 Ok(()) => Self::OK,
298 Err(status) => status,
299 }
300 }
301}
302
303impl From<Status> for Result<(), Status> {
304 fn from(src: Status) -> Result<(), Status> {
305 Status::ok(src.into_raw())
306 }
307}
308
309impl From<core::convert::Infallible> for Status {
310 fn from(x: core::convert::Infallible) -> Status {
311 match x {}
312 }
313}
314
315#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
321#[repr(transparent)]
322pub struct ErrorStatus(core::num::NonZero<sys::zx_status_t>);
323
324impl ErrorStatus {
325 pub fn from_raw(raw: sys::zx_status_t) -> Option<Self> {
326 core::num::NonZero::new(raw).map(ErrorStatus)
327 }
328
329 pub fn into_raw(self) -> sys::zx_status_t {
330 self.0.get()
331 }
332
333 pub fn ok(raw: sys::zx_status_t) -> Result<(), Self> {
334 match core::num::NonZero::new(raw) {
335 Some(err) => Err(ErrorStatus(err)),
336 None => Ok(()),
337 }
338 }
339}
340
341impl From<Status> for ErrorStatus {
342 #[inline]
343 fn from(status: Status) -> Self {
344 ErrorStatus(
345 core::num::NonZero::new(status.into_raw())
346 .expect("Attempted to convert Status::OK into ErrorStatus"),
347 )
348 }
349}
350
351impl From<ErrorStatus> for Status {
352 #[inline]
353 fn from(err: ErrorStatus) -> Self {
354 Status::from_raw(err.0.get())
355 }
356}
357
358impl fmt::Debug for ErrorStatus {
359 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
360 fmt::Debug::fmt(&Status::from_raw(self.0.get()), f)
361 }
362}
363
364impl fmt::Display for ErrorStatus {
365 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
366 fmt::Display::fmt(&Status::from_raw(self.0.get()), f)
367 }
368}
369
370impl core::error::Error for ErrorStatus {}
371
372#[cfg(test)]
373mod test {
374 extern crate std;
375 use super::Status;
376
377 #[test]
378 fn status_debug_format() {
379 let cases = [
380 ("Status(OK)", Status::OK),
381 ("Status(BAD_SYSCALL)", Status::BAD_SYSCALL),
382 ("Status(NEXT)", Status::NEXT),
383 ("Status(-5050)", Status(-5050)),
384 ];
385 for &(expected, value) in &cases {
386 assert_eq!(expected, std::format!("{value:?}"));
387 }
388 }
389
390 #[test]
391 fn status_into_result() {
392 let ok_result: Result<(), Status> = Status::OK.into();
393 assert_eq!(ok_result, Ok(()));
394
395 let err_result: Result<(), Status> = Status::BAD_SYSCALL.into();
396 assert_eq!(err_result, Err(Status::BAD_SYSCALL));
397 }
398
399 #[test]
400 fn error_status_conversions() {
401 let err_res: Result<(), super::ErrorStatus> = Err(Status::BAD_SYSCALL.into());
402 assert_eq!(err_res, Err(Status::BAD_SYSCALL.into()));
403 }
404}