1 use std::ffi::NulError;
2 use std::io;
3 use sys;
4 
5 /// Status type indicating the result of a Fuchsia syscall.
6 ///
7 /// This type is generally used to indicate the reason for an error.
8 /// While this type can contain `Status::OK` (`ZX_OK` in C land), elements of this type are
9 /// generally constructed using the `ok` method, which checks for `ZX_OK` and returns a
10 /// `Result<(), Status>` appropriately.
11 #[repr(C)]
12 #[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
13 pub struct Status(sys::zx_status_t);
14 impl Status {
15     /// Returns `Ok(())` if the status was `OK`,
16     /// otherwise returns `Err(status)`.
ok(raw: sys::zx_status_t) -> Result<(), Status>17     pub fn ok(raw: sys::zx_status_t) -> Result<(), Status> {
18         if raw == Status::OK.0 {
19             Ok(())
20         } else {
21             Err(Status(raw))
22         }
23     }
24 
from_raw(raw: sys::zx_status_t) -> Self25     pub fn from_raw(raw: sys::zx_status_t) -> Self {
26         Status(raw)
27     }
28 
into_raw(self) -> sys::zx_status_t29     pub fn into_raw(self) -> sys::zx_status_t {
30         self.0
31     }
32 }
33 assoc_consts!(Status, [
34     OK                 = sys::ZX_OK;
35     INTERNAL           = sys::ZX_ERR_INTERNAL;
36     NOT_SUPPORTED      = sys::ZX_ERR_NOT_SUPPORTED;
37     NO_RESOURCES       = sys::ZX_ERR_NO_RESOURCES;
38     NO_MEMORY          = sys::ZX_ERR_NO_MEMORY;
39     CALL_FAILED        = sys::ZX_ERR_CALL_FAILED;
40     INTERRUPTED_RETRY  = sys::ZX_ERR_INTERRUPTED_RETRY;
41     INVALID_ARGS       = sys::ZX_ERR_INVALID_ARGS;
42     BAD_HANDLE         = sys::ZX_ERR_BAD_HANDLE;
43     WRONG_TYPE         = sys::ZX_ERR_WRONG_TYPE;
44     BAD_SYSCALL        = sys::ZX_ERR_BAD_SYSCALL;
45     OUT_OF_RANGE       = sys::ZX_ERR_OUT_OF_RANGE;
46     BUFFER_TOO_SMALL   = sys::ZX_ERR_BUFFER_TOO_SMALL;
47     BAD_STATE          = sys::ZX_ERR_BAD_STATE;
48     TIMED_OUT          = sys::ZX_ERR_TIMED_OUT;
49     SHOULD_WAIT        = sys::ZX_ERR_SHOULD_WAIT;
50     CANCELED           = sys::ZX_ERR_CANCELED;
51     PEER_CLOSED        = sys::ZX_ERR_PEER_CLOSED;
52     NOT_FOUND          = sys::ZX_ERR_NOT_FOUND;
53     ALREADY_EXISTS     = sys::ZX_ERR_ALREADY_EXISTS;
54     ALREADY_BOUND      = sys::ZX_ERR_ALREADY_BOUND;
55     UNAVAILABLE        = sys::ZX_ERR_UNAVAILABLE;
56     ACCESS_DENIED      = sys::ZX_ERR_ACCESS_DENIED;
57     IO                 = sys::ZX_ERR_IO;
58     IO_REFUSED         = sys::ZX_ERR_IO_REFUSED;
59     IO_DATA_INTEGRITY  = sys::ZX_ERR_IO_DATA_INTEGRITY;
60     IO_DATA_LOSS       = sys::ZX_ERR_IO_DATA_LOSS;
61     BAD_PATH           = sys::ZX_ERR_BAD_PATH;
62     NOT_DIR            = sys::ZX_ERR_NOT_DIR;
63     NOT_FILE           = sys::ZX_ERR_NOT_FILE;
64     FILE_BIG           = sys::ZX_ERR_FILE_BIG;
65     NO_SPACE           = sys::ZX_ERR_NO_SPACE;
66     STOP               = sys::ZX_ERR_STOP;
67     NEXT               = sys::ZX_ERR_NEXT;
68 ]);
69 
70 impl Status {
into_io_error(self) -> io::Error71     pub fn into_io_error(self) -> io::Error {
72         self.into()
73     }
74 }
75 
76 impl From<io::ErrorKind> for Status {
from(kind: io::ErrorKind) -> Self77     fn from(kind: io::ErrorKind) -> Self {
78         use std::io::ErrorKind::*;
79         match kind {
80             NotFound => Status::NOT_FOUND,
81             PermissionDenied => Status::ACCESS_DENIED,
82             ConnectionRefused => Status::IO_REFUSED,
83             ConnectionAborted => Status::PEER_CLOSED,
84             AddrInUse => Status::ALREADY_BOUND,
85             AddrNotAvailable => Status::UNAVAILABLE,
86             BrokenPipe => Status::PEER_CLOSED,
87             AlreadyExists => Status::ALREADY_EXISTS,
88             WouldBlock => Status::SHOULD_WAIT,
89             InvalidInput => Status::INVALID_ARGS,
90             TimedOut => Status::TIMED_OUT,
91             Interrupted => Status::INTERRUPTED_RETRY,
92             UnexpectedEof |
93             WriteZero |
94             ConnectionReset |
95             NotConnected |
96             Other | _ => Status::IO,
97         }
98     }
99 }
100 
101 impl From<Status> for io::ErrorKind {
from(status: Status) -> io::ErrorKind102     fn from(status: Status) -> io::ErrorKind {
103         use std::io::ErrorKind::*;
104         match status {
105             Status::INTERRUPTED_RETRY => Interrupted,
106             Status::BAD_HANDLE => BrokenPipe,
107             Status::TIMED_OUT => TimedOut,
108             Status::SHOULD_WAIT => WouldBlock,
109             Status::PEER_CLOSED => ConnectionAborted,
110             Status::NOT_FOUND => NotFound,
111             Status::ALREADY_EXISTS => AlreadyExists,
112             Status::ALREADY_BOUND => AlreadyExists,
113             Status::UNAVAILABLE => AddrNotAvailable,
114             Status::ACCESS_DENIED => PermissionDenied,
115             Status::IO_REFUSED => ConnectionRefused,
116             Status::IO_DATA_INTEGRITY => InvalidData,
117 
118             Status::BAD_PATH |
119             Status::INVALID_ARGS |
120             Status::OUT_OF_RANGE |
121             Status::WRONG_TYPE => InvalidInput,
122 
123             Status::OK |
124             Status::NEXT |
125             Status::STOP |
126             Status::NO_SPACE |
127             Status::FILE_BIG |
128             Status::NOT_FILE |
129             Status::NOT_DIR |
130             Status::IO_DATA_LOSS |
131             Status::IO |
132             Status::CANCELED |
133             Status::BAD_STATE |
134             Status::BUFFER_TOO_SMALL |
135             Status::BAD_SYSCALL |
136             Status::INTERNAL |
137             Status::NOT_SUPPORTED |
138             Status::NO_RESOURCES |
139             Status::NO_MEMORY |
140             Status::CALL_FAILED |
141             _ => Other,
142         }
143     }
144 }
145 
146 impl From<io::Error> for Status {
from(err: io::Error) -> Status147     fn from(err: io::Error) -> Status {
148         err.kind().into()
149     }
150 }
151 
152 impl From<Status> for io::Error {
from(status: Status) -> io::Error153     fn from(status: Status) -> io::Error {
154         io::Error::from(io::ErrorKind::from(status))
155     }
156 }
157 
158 impl From<NulError> for Status {
from(_error: NulError) -> Status159     fn from(_error: NulError) -> Status {
160         Status::INVALID_ARGS
161     }
162 }
163