Skip to main content

runtime_capabilities/
data.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::{CapabilityBound, RemoteError};
6use fidl_fuchsia_component_sandbox as fsandbox;
7use flyweights::{FlyByteStr, FlyStr};
8use std::fmt::Debug;
9use std::sync::Arc;
10
11/// A capability that holds immutable data.
12///
13/// `Bytes` and `String` use pointer-sized flyweight types (`8 B` on 64-bit, with inline SSO for
14/// <= 7 bytes) rather than 16-byte fat pointers (`Arc<[u8]>` / `Arc<str>`) so that `Data` and
15/// `Capability` stay 16 bytes while `Int64` and `Uint64` remain inline without heap allocation.
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub enum Data {
18    Bytes(FlyByteStr),
19    String(FlyStr),
20    Int64(i64),
21    Uint64(u64),
22}
23
24impl CapabilityBound for Data {
25    fn debug_typename() -> &'static str {
26        "Data"
27    }
28}
29
30impl TryFrom<fsandbox::Data> for Data {
31    type Error = RemoteError;
32
33    fn try_from(data_capability: fsandbox::Data) -> Result<Self, Self::Error> {
34        match data_capability {
35            fsandbox::Data::Bytes(bytes) => Ok(Self::Bytes(bytes.into())),
36            fsandbox::Data::String(string) => Ok(Self::String(string.into())),
37            fsandbox::Data::Int64(num) => Ok(Self::Int64(num)),
38            fsandbox::Data::Uint64(num) => Ok(Self::Uint64(num)),
39            fsandbox::DataUnknown!() => Err(RemoteError::UnknownVariant),
40        }
41    }
42}
43
44impl From<Data> for fsandbox::Data {
45    fn from(data: Data) -> Self {
46        match data {
47            Data::Bytes(bytes) => fsandbox::Data::Bytes(bytes.into()),
48            Data::String(string) => fsandbox::Data::String(string.into()),
49            Data::Int64(num) => fsandbox::Data::Int64(num),
50            Data::Uint64(num) => fsandbox::Data::Uint64(num),
51        }
52    }
53}
54
55impl From<Data> for fsandbox::Capability {
56    fn from(data: Data) -> Self {
57        Self::Data(data.into())
58    }
59}
60
61impl From<Arc<Data>> for crate::Capability {
62    fn from(data: Arc<Data>) -> Self {
63        crate::Capability::Data((*data).clone())
64    }
65}
66
67impl TryFrom<crate::Capability> for Arc<Data> {
68    type Error = <Data as TryFrom<crate::Capability>>::Error;
69
70    fn try_from(capability: crate::Capability) -> Result<Self, Self::Error> {
71        let data: Data = capability.try_into()?;
72        Ok(Arc::new(data))
73    }
74}