1use crate::Router;
6use from_enum::FromEnum;
7use router_error::Explain;
8use std::fmt::Debug;
9use thiserror::Error;
10use zx_status;
11
12#[derive(Error, Debug, Clone)]
13pub enum ConversionError {
14 #[error("invalid `fuchsia.io` node name: name `{0}` is too long")]
15 ParseNameErrorTooLong(String),
16
17 #[error("invalid `fuchsia.io` node name: name cannot be empty")]
18 ParseNameErrorEmpty,
19
20 #[error("invalid `fuchsia.io` node name: name cannot be `.`")]
21 ParseNameErrorDot,
22
23 #[error("invalid `fuchsia.io` node name: name cannot be `..`")]
24 ParseNameErrorDotDot,
25
26 #[error("invalid `fuchsia.io` node name: name cannot contain `/`")]
27 ParseNameErrorSlash,
28
29 #[error("invalid `fuchsia.io` node name: name cannot contain embedded NUL")]
30 ParseNameErrorEmbeddedNul,
31
32 #[error("conversion to type is not supported")]
33 NotSupported,
34
35 #[error("conversion failed because a capability could not be cloned")]
36 NotCloneable,
37
38 #[error("value at `{key}` could not be converted: {err}")]
39 Nested {
40 key: String,
41 #[source]
42 err: Box<ConversionError>,
43 },
44}
45
46#[cfg(target_os = "fuchsia")]
47impl From<vfs::name::ParseNameError> for ConversionError {
48 fn from(parse_name_error: vfs::name::ParseNameError) -> Self {
49 match parse_name_error {
50 vfs::name::ParseNameError::TooLong(s) => ConversionError::ParseNameErrorTooLong(s),
51 vfs::name::ParseNameError::Empty => ConversionError::ParseNameErrorEmpty,
52 vfs::name::ParseNameError::Dot => ConversionError::ParseNameErrorDot,
53 vfs::name::ParseNameError::DotDot => ConversionError::ParseNameErrorDotDot,
54 vfs::name::ParseNameError::Slash => ConversionError::ParseNameErrorSlash,
55 vfs::name::ParseNameError::EmbeddedNul => ConversionError::ParseNameErrorEmbeddedNul,
56 }
57 }
58}
59
60#[derive(Error, Debug)]
62pub enum RemoteError {
63 #[error("unknown FIDL variant")]
64 UnknownVariant,
65
66 #[error("unregistered capability; only capabilities created by sandbox are allowed")]
67 Unregistered,
68
69 #[error("registered capability had the wrong type")]
70 BadCapability,
71}
72
73impl Explain for RemoteError {
74 fn as_zx_status(&self) -> zx_status::Status {
75 match self {
76 RemoteError::UnknownVariant => zx_status::Status::NOT_SUPPORTED,
77 RemoteError::Unregistered => zx_status::Status::INVALID_ARGS,
78 RemoteError::BadCapability => zx_status::Status::INVALID_ARGS,
79 }
80 }
81}
82
83#[derive(FromEnum, Debug)]
84pub enum Capability {
85 Unit(crate::Unit),
86 Connector(crate::Connector),
87 DirConnector(crate::DirConnector),
88 Dictionary(crate::Dict),
89 Data(crate::Data),
90 Directory(crate::Directory),
91 Handle(crate::Handle),
92 ConnectorRouter(crate::Router<crate::Connector>),
93 DictionaryRouter(crate::Router<crate::Dict>),
94 DirEntryRouter(crate::Router<crate::DirEntry>),
95 DirConnectorRouter(crate::Router<crate::DirConnector>),
96 DataRouter(crate::Router<crate::Data>),
97 Instance(crate::WeakInstanceToken),
98 DirEntry(crate::DirEntry),
99}
100
101impl Capability {
102 pub fn to_dictionary(self) -> Option<crate::Dict> {
103 match self {
104 Self::Dictionary(d) => Some(d),
105 _ => None,
106 }
107 }
108
109 pub fn try_clone(&self) -> Result<Self, ()> {
110 match self {
111 Self::Connector(s) => Ok(Self::Connector(s.clone())),
112 Self::DirConnector(s) => Ok(Self::DirConnector(s.clone())),
113 Self::ConnectorRouter(s) => Ok(Self::ConnectorRouter(s.clone())),
114 Self::DictionaryRouter(s) => Ok(Self::DictionaryRouter(s.clone())),
115 Self::DirEntryRouter(s) => Ok(Self::DirEntryRouter(s.clone())),
116 Self::DirConnectorRouter(s) => Ok(Self::DirConnectorRouter(s.clone())),
117 Self::DataRouter(s) => Ok(Self::DataRouter(s.clone())),
118 Self::Dictionary(s) => Ok(Self::Dictionary(s.clone())),
119 Self::Data(s) => Ok(Self::Data(s.clone())),
120 Self::Unit(s) => Ok(Self::Unit(s.clone())),
121 Self::Directory(_) => {
122 Err(())
124 }
125 Self::Handle(s) => Ok(Self::Handle(s.try_clone()?)),
126 Self::Instance(s) => Ok(Self::Instance(s.clone())),
127 Self::DirEntry(s) => Ok(Self::DirEntry(s.clone())),
128 }
129 }
130
131 pub fn debug_typename(&self) -> &'static str {
132 match self {
133 Self::Connector(_) => crate::Connector::debug_typename(),
134 Self::DirConnector(_) => crate::DirConnector::debug_typename(),
135 Self::ConnectorRouter(_) => crate::Router::<crate::Connector>::debug_typename(),
136 Self::DictionaryRouter(_) => crate::Router::<crate::Dict>::debug_typename(),
137 Self::DirEntryRouter(_) => crate::Router::<crate::DirEntry>::debug_typename(),
138 Self::DirConnectorRouter(_) => crate::Router::<crate::DirConnector>::debug_typename(),
139 Self::DataRouter(_) => crate::Router::<crate::Data>::debug_typename(),
140 Self::Dictionary(_) => crate::Dict::debug_typename(),
141 Self::Data(_) => crate::Data::debug_typename(),
142 Self::Unit(_) => crate::Unit::debug_typename(),
143 Self::Directory(_) => crate::Directory::debug_typename(),
144 Self::Handle(_) => crate::Handle::debug_typename(),
145 Self::Instance(_) => "Instance",
146 Self::DirEntry(_) => crate::DirEntry::debug_typename(),
147 }
148 }
149}
150
151impl TryFrom<Capability> for crate::Connector {
152 type Error = ();
153
154 fn try_from(c: Capability) -> Result<Self, Self::Error> {
155 match c {
156 Capability::Connector(c) => Ok(c),
157 _ => Err(()),
158 }
159 }
160}
161
162impl TryFrom<Capability> for crate::DirConnector {
163 type Error = ();
164
165 fn try_from(c: Capability) -> Result<Self, Self::Error> {
166 match c {
167 Capability::DirConnector(c) => Ok(c),
168 _ => Err(()),
169 }
170 }
171}
172
173impl TryFrom<Capability> for crate::Dict {
174 type Error = ();
175
176 fn try_from(c: Capability) -> Result<Self, Self::Error> {
177 match c {
178 Capability::Dictionary(c) => Ok(c),
179 _ => Err(()),
180 }
181 }
182}
183
184impl TryFrom<Capability> for crate::Directory {
185 type Error = ();
186
187 fn try_from(c: Capability) -> Result<Self, Self::Error> {
188 match c {
189 Capability::Directory(c) => Ok(c),
190 _ => Err(()),
191 }
192 }
193}
194
195impl TryFrom<Capability> for crate::DirEntry {
196 type Error = ();
197
198 fn try_from(c: Capability) -> Result<Self, Self::Error> {
199 match c {
200 Capability::DirEntry(c) => Ok(c),
201 _ => Err(()),
202 }
203 }
204}
205
206impl TryFrom<Capability> for crate::Data {
207 type Error = ();
208
209 fn try_from(c: Capability) -> Result<Self, Self::Error> {
210 match c {
211 Capability::Data(c) => Ok(c),
212 _ => Err(()),
213 }
214 }
215}
216
217impl TryFrom<Capability> for crate::Handle {
218 type Error = ();
219
220 fn try_from(c: Capability) -> Result<Self, Self::Error> {
221 match c {
222 Capability::Handle(r) => Ok(r),
223 _ => Err(()),
224 }
225 }
226}
227
228impl TryFrom<Capability> for crate::Unit {
229 type Error = ();
230
231 fn try_from(c: Capability) -> Result<Self, Self::Error> {
232 match c {
233 Capability::Unit(r) => Ok(r),
234 _ => Err(()),
235 }
236 }
237}
238
239impl TryFrom<Capability> for Router<crate::Dict> {
240 type Error = ();
241
242 fn try_from(c: Capability) -> Result<Self, Self::Error> {
243 match c {
244 Capability::DictionaryRouter(c) => Ok(c),
245 _ => Err(()),
246 }
247 }
248}
249
250impl TryFrom<Capability> for Router<crate::DirConnector> {
251 type Error = ();
252
253 fn try_from(c: Capability) -> Result<Self, Self::Error> {
254 match c {
255 Capability::DirConnectorRouter(c) => Ok(c),
256 _ => Err(()),
257 }
258 }
259}
260
261impl TryFrom<Capability> for Router<crate::DirEntry> {
262 type Error = ();
263
264 fn try_from(c: Capability) -> Result<Self, Self::Error> {
265 match c {
266 Capability::DirEntryRouter(c) => Ok(c),
267 _ => Err(()),
268 }
269 }
270}
271
272impl TryFrom<Capability> for Router<crate::Connector> {
273 type Error = ();
274
275 fn try_from(c: Capability) -> Result<Self, Self::Error> {
276 match c {
277 Capability::ConnectorRouter(c) => Ok(c),
278 _ => Err(()),
279 }
280 }
281}
282
283impl TryFrom<Capability> for Router<crate::Data> {
284 type Error = ();
285
286 fn try_from(c: Capability) -> Result<Self, Self::Error> {
287 match c {
288 Capability::DataRouter(c) => Ok(c),
289 _ => Err(()),
290 }
291 }
292}
293
294pub trait CapabilityBound: Into<Capability> + TryFrom<Capability> + Send + Sync + 'static {
297 fn debug_typename() -> &'static str;
298}