1use zx::Status;
6
7#[derive(Debug)]
14pub enum DriverError {
15 Status(Status),
17 Anyhow(anyhow::Error),
19 Fidl(fidl::Error),
21}
22
23impl DriverError {
24 pub fn log_to_status(self) -> Status {
26 match self {
27 DriverError::Status(status) => status,
28 DriverError::Anyhow(err) => {
29 if let Some(status) = err.root_cause().downcast_ref::<Status>() {
30 *status
31 } else {
32 log::error!("Driver failed with internal error: {:?}", err);
33 Status::INTERNAL
34 }
35 }
36 DriverError::Fidl(err) => {
37 log::error!("Driver failed with FIDL error: {:?}", err);
38 Status::INTERNAL
39 }
40 }
41 }
42}
43
44impl From<Status> for DriverError {
45 fn from(status: Status) -> Self {
46 DriverError::Status(status)
47 }
48}
49
50impl From<anyhow::Error> for DriverError {
51 fn from(err: anyhow::Error) -> Self {
52 DriverError::Anyhow(err)
53 }
54}
55
56impl From<fidl::Error> for DriverError {
57 fn from(err: fidl::Error) -> Self {
58 DriverError::Fidl(err)
59 }
60}
61
62impl std::fmt::Display for DriverError {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 match self {
65 DriverError::Status(status) => write!(f, "Status: {status}"),
66 DriverError::Anyhow(err) => write!(f, "Anyhow: {err}"),
67 DriverError::Fidl(err) => write!(f, "FIDL: {err}"),
68 }
69 }
70}
71
72impl std::error::Error for DriverError {
73 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
74 match self {
75 DriverError::Status(status) => Some(status),
76 DriverError::Anyhow(err) => Some(err.as_ref()),
77 DriverError::Fidl(err) => Some(err),
78 }
79 }
80}
81
82impl From<fidl_next::Error<Status>> for DriverError {
83 fn from(err: fidl_next::Error<Status>) -> Self {
84 match err {
85 fidl_next::Error::Encode(encode_err) => {
86 log::error!("FIDL encode error: {:?}", encode_err);
87 DriverError::Status(Status::INTERNAL)
88 }
89 fidl_next::Error::Decode(decode_err) => {
90 log::error!("FIDL decode error: {:?}", decode_err);
91 DriverError::Status(Status::INTERNAL)
92 }
93 fidl_next::Error::Protocol(protocol_err) => match protocol_err {
94 fidl_next::ProtocolError::TransportError(status) => DriverError::Status(status),
95 fidl_next::ProtocolError::PeerClosed => DriverError::Status(Status::PEER_CLOSED),
96 _ => {
97 log::error!("FIDL protocol error: {:?}", protocol_err);
98 DriverError::Status(Status::INTERNAL)
99 }
100 },
101 }
102 }
103}
104
105pub trait FlexibleResultExt<T> {
107 fn into_driver_result(self) -> Result<T, DriverError>;
109}
110
111impl<T> FlexibleResultExt<T> for fidl_next::FlexibleResult<T, i32> {
112 fn into_driver_result(self) -> Result<T, DriverError> {
113 match self {
114 fidl_next::FlexibleResult::Ok(t) => Ok(t),
115 fidl_next::FlexibleResult::Err(raw_status) => {
116 Err(DriverError::Status(Status::from_raw(raw_status)))
117 }
118 fidl_next::FlexibleResult::FrameworkErr(err) => {
119 log::error!("FIDL framework error: {:?}", err);
120 Err(DriverError::Status(Status::INTERNAL))
121 }
122 }
123 }
124}
125
126pub trait FlexibleExt<T> {
128 fn into_driver_result(self) -> Result<T, DriverError>;
130}
131
132impl<T> FlexibleExt<T> for fidl_next::Flexible<T> {
133 fn into_driver_result(self) -> Result<T, DriverError> {
134 match self {
135 fidl_next::Flexible::Ok(t) => Ok(t),
136 fidl_next::Flexible::FrameworkErr(err) => {
137 log::error!("FIDL framework error: {:?}", err);
138 Err(DriverError::Status(Status::INTERNAL))
139 }
140 }
141 }
142}