blob: 92d24e5753aa0bd513a5572144ddb52d97f44ed3 [file]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::Router;
use from_enum::FromEnum;
use router_error::Explain;
use std::fmt::Debug;
use std::sync::Arc;
use thiserror::Error;
use zx_status;
#[derive(Error, Debug, Clone)]
pub enum ConversionError {
#[error("conversion to type is not supported")]
NotSupported,
}
/// Errors arising from conversion between Rust and FIDL types.
#[derive(Error, Debug)]
pub enum RemoteError {
#[error("unknown FIDL variant")]
UnknownVariant,
#[error("unregistered capability; only capabilities created by sandbox are allowed")]
Unregistered,
#[error("registered capability had the wrong type")]
BadCapability,
}
impl Explain for RemoteError {
fn as_zx_status(&self) -> zx_status::Status {
match self {
RemoteError::UnknownVariant => zx_status::Status::NOT_SUPPORTED,
RemoteError::Unregistered => zx_status::Status::INVALID_ARGS,
RemoteError::BadCapability => zx_status::Status::INVALID_ARGS,
}
}
}
#[derive(FromEnum, Debug, Clone)]
pub enum Capability {
Connector(Arc<crate::Connector>),
DirConnector(Arc<crate::DirConnector>),
Dictionary(Arc<crate::Dictionary>),
Data(crate::Data),
Handle(Arc<crate::Handle>),
ConnectorRouter(Arc<crate::Router<crate::Connector>>),
DictionaryRouter(Arc<crate::Router<crate::Dictionary>>),
DirConnectorRouter(Arc<crate::Router<crate::DirConnector>>),
DataRouter(Arc<crate::Router<crate::Data>>),
Instance(Arc<crate::WeakInstanceToken>),
}
impl Capability {
pub fn to_dictionary(self) -> Option<Arc<crate::Dictionary>> {
match self {
Self::Dictionary(d) => Some(d),
_ => None,
}
}
pub fn debug_typename(&self) -> &'static str {
match self {
Self::Connector(_) => crate::Connector::debug_typename(),
Self::DirConnector(_) => crate::DirConnector::debug_typename(),
Self::ConnectorRouter(_) => crate::Router::<crate::Connector>::debug_typename(),
Self::DictionaryRouter(_) => crate::Router::<crate::Dictionary>::debug_typename(),
Self::DirConnectorRouter(_) => crate::Router::<crate::DirConnector>::debug_typename(),
Self::DataRouter(_) => crate::Router::<crate::Data>::debug_typename(),
Self::Dictionary(_) => crate::Dictionary::debug_typename(),
Self::Data(_) => crate::Data::debug_typename(),
Self::Handle(_) => crate::Handle::debug_typename(),
Self::Instance(_) => "Instance",
}
}
}
impl TryFrom<Capability> for Arc<crate::Connector> {
type Error = ();
fn try_from(c: Capability) -> Result<Self, Self::Error> {
match c {
Capability::Connector(c) => Ok(c),
_ => Err(()),
}
}
}
impl TryFrom<Capability> for Arc<crate::DirConnector> {
type Error = ();
fn try_from(c: Capability) -> Result<Self, Self::Error> {
match c {
Capability::DirConnector(c) => Ok(c),
_ => Err(()),
}
}
}
impl TryFrom<Capability> for Arc<crate::Dictionary> {
type Error = ();
fn try_from(c: Capability) -> Result<Self, Self::Error> {
match c {
Capability::Dictionary(c) => Ok(c),
_ => Err(()),
}
}
}
impl TryFrom<Capability> for crate::Data {
type Error = ();
fn try_from(c: Capability) -> Result<Self, Self::Error> {
match c {
Capability::Data(c) => Ok(c),
_ => Err(()),
}
}
}
impl TryFrom<Capability> for Arc<Router<crate::Dictionary>> {
type Error = ();
fn try_from(c: Capability) -> Result<Self, Self::Error> {
match c {
Capability::DictionaryRouter(c) => Ok(c),
_ => Err(()),
}
}
}
impl TryFrom<Capability> for Arc<Router<crate::DirConnector>> {
type Error = ();
fn try_from(c: Capability) -> Result<Self, Self::Error> {
match c {
Capability::DirConnectorRouter(c) => Ok(c),
_ => Err(()),
}
}
}
impl TryFrom<Capability> for Arc<Router<crate::Connector>> {
type Error = ();
fn try_from(c: Capability) -> Result<Self, Self::Error> {
match c {
Capability::ConnectorRouter(c) => Ok(c),
_ => Err(()),
}
}
}
impl TryFrom<Capability> for Arc<Router<crate::Data>> {
type Error = ();
fn try_from(c: Capability) -> Result<Self, Self::Error> {
match c {
Capability::DataRouter(c) => Ok(c),
_ => Err(()),
}
}
}
impl TryFrom<Capability> for Arc<crate::WeakInstanceToken> {
type Error = ();
fn try_from(c: Capability) -> Result<Self, Self::Error> {
match c {
Capability::Instance(i) => Ok(i),
_ => Err(()),
}
}
}
/// Parent trait implemented by all capability types. Useful for defining interfaces that
/// generic over a capability type.
pub trait CapabilityBound: Send + Sync + 'static {
fn debug_typename() -> &'static str;
/// Converts this capability into a directory entry.
///
/// This is on the "main" capability trait because this is something supported by (almost)
/// every capability type, and all capability types are expected to either support this or be
/// able to report that they cannot (i.e. return an error when this is called).
#[cfg(target_os = "fuchsia")]
fn try_into_directory_entry(
self: Arc<Self>,
_scope: vfs::execution_scope::ExecutionScope,
_token: Arc<crate::WeakInstanceToken>,
) -> Result<Arc<dyn vfs::directory::entry::DirectoryEntry>, crate::ConversionError> {
Err(ConversionError::NotSupported)
}
}