runtime_capabilities/
capability.rs1use 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, Clone)]
84pub enum Capability {
85 Connector(crate::Connector),
86 DirConnector(crate::DirConnector),
87 Dictionary(crate::Dictionary),
88 Data(crate::Data),
89 Handle(crate::Handle),
90 ConnectorRouter(crate::Router<crate::Connector>),
91 DictionaryRouter(crate::Router<crate::Dictionary>),
92 DirConnectorRouter(crate::Router<crate::DirConnector>),
93 DataRouter(crate::Router<crate::Data>),
94 Instance(crate::WeakInstanceToken),
95}
96
97impl Capability {
98 pub fn to_dictionary(self) -> Option<crate::Dictionary> {
99 match self {
100 Self::Dictionary(d) => Some(d),
101 _ => None,
102 }
103 }
104
105 pub fn debug_typename(&self) -> &'static str {
106 match self {
107 Self::Connector(_) => crate::Connector::debug_typename(),
108 Self::DirConnector(_) => crate::DirConnector::debug_typename(),
109 Self::ConnectorRouter(_) => crate::Router::<crate::Connector>::debug_typename(),
110 Self::DictionaryRouter(_) => crate::Router::<crate::Dictionary>::debug_typename(),
111 Self::DirConnectorRouter(_) => crate::Router::<crate::DirConnector>::debug_typename(),
112 Self::DataRouter(_) => crate::Router::<crate::Data>::debug_typename(),
113 Self::Dictionary(_) => crate::Dictionary::debug_typename(),
114 Self::Data(_) => crate::Data::debug_typename(),
115 Self::Handle(_) => crate::Handle::debug_typename(),
116 Self::Instance(_) => "Instance",
117 }
118 }
119}
120
121impl TryFrom<Capability> for crate::Connector {
122 type Error = ();
123
124 fn try_from(c: Capability) -> Result<Self, Self::Error> {
125 match c {
126 Capability::Connector(c) => Ok(c),
127 _ => Err(()),
128 }
129 }
130}
131
132impl TryFrom<Capability> for crate::DirConnector {
133 type Error = ();
134
135 fn try_from(c: Capability) -> Result<Self, Self::Error> {
136 match c {
137 Capability::DirConnector(c) => Ok(c),
138 _ => Err(()),
139 }
140 }
141}
142
143impl TryFrom<Capability> for crate::Dictionary {
144 type Error = ();
145
146 fn try_from(c: Capability) -> Result<Self, Self::Error> {
147 match c {
148 Capability::Dictionary(c) => Ok(c),
149 _ => Err(()),
150 }
151 }
152}
153
154impl TryFrom<Capability> for crate::Data {
155 type Error = ();
156
157 fn try_from(c: Capability) -> Result<Self, Self::Error> {
158 match c {
159 Capability::Data(c) => Ok(c),
160 _ => Err(()),
161 }
162 }
163}
164
165impl TryFrom<Capability> for crate::Handle {
166 type Error = ();
167
168 fn try_from(c: Capability) -> Result<Self, Self::Error> {
169 match c {
170 Capability::Handle(r) => Ok(r),
171 _ => Err(()),
172 }
173 }
174}
175
176impl TryFrom<Capability> for Router<crate::Dictionary> {
177 type Error = ();
178
179 fn try_from(c: Capability) -> Result<Self, Self::Error> {
180 match c {
181 Capability::DictionaryRouter(c) => Ok(c),
182 _ => Err(()),
183 }
184 }
185}
186
187impl TryFrom<Capability> for Router<crate::DirConnector> {
188 type Error = ();
189
190 fn try_from(c: Capability) -> Result<Self, Self::Error> {
191 match c {
192 Capability::DirConnectorRouter(c) => Ok(c),
193 _ => Err(()),
194 }
195 }
196}
197
198impl TryFrom<Capability> for Router<crate::Connector> {
199 type Error = ();
200
201 fn try_from(c: Capability) -> Result<Self, Self::Error> {
202 match c {
203 Capability::ConnectorRouter(c) => Ok(c),
204 _ => Err(()),
205 }
206 }
207}
208
209impl TryFrom<Capability> for Router<crate::Data> {
210 type Error = ();
211
212 fn try_from(c: Capability) -> Result<Self, Self::Error> {
213 match c {
214 Capability::DataRouter(c) => Ok(c),
215 _ => Err(()),
216 }
217 }
218}
219
220impl TryFrom<Capability> for crate::WeakInstanceToken {
221 type Error = ();
222
223 fn try_from(c: Capability) -> Result<Self, Self::Error> {
224 match c {
225 Capability::Instance(i) => Ok(i),
226 _ => Err(()),
227 }
228 }
229}
230
231pub trait CapabilityBound: Into<Capability> + TryFrom<Capability> + Send + Sync + 'static {
234 fn debug_typename() -> &'static str;
235}