routing/bedrock/
request_metadata.rs
1use crate::rights::Rights;
6use cm_rust::Availability;
7use sandbox::{Capability, Data, Dict, DictKey};
8use {fidl_fuchsia_component_sandbox as fsandbox, fidl_fuchsia_io as fio};
9
10pub const METADATA_KEY_TYPE: &'static str = "type";
12
13pub const TYPE_PROTOCOL: &'static str = "protocol";
15pub const TYPE_DICTIONARY: &'static str = "dictionary";
16pub const TYPE_CONFIG: &'static str = "configuration";
17
18pub trait Metadata<T> {
20 const KEY: &'static str;
22
23 fn set_metadata(&self, value: T);
25
26 fn get_metadata(&self) -> Option<T>;
28}
29
30impl Metadata<Availability> for Dict {
31 const KEY: &'static str = "availability";
32
33 fn set_metadata(&self, value: Availability) {
34 let key = DictKey::new(<Self as Metadata<Availability>>::KEY)
35 .expect("dict key creation failed unexpectedly");
36 match self.insert(key, Capability::Data(Data::String(value.to_string()))) {
37 Ok(()) | Err(fsandbox::CapabilityStoreError::ItemAlreadyExists) => (),
42 Err(e) => panic!("unexpected error variant returned from Dict::insert(): {e:?}"),
44 }
45 }
46
47 fn get_metadata(&self) -> Option<Availability> {
48 let key = DictKey::new(<Self as Metadata<Availability>>::KEY)
49 .expect("dict key creation failed unexpectedly");
50 let capability = self.get(&key).ok()??;
51 match capability {
52 Capability::Data(Data::String(availability)) => match availability.as_str() {
53 "Optional" => Some(Availability::Optional),
54 "Required" => Some(Availability::Required),
55 "SameAsTarget" => Some(Availability::SameAsTarget),
56 "Transitional" => Some(Availability::Transitional),
57 _ => None,
58 },
59 _ => None,
60 }
61 }
62}
63
64impl Metadata<Rights> for Dict {
65 const KEY: &'static str = "rights";
66
67 fn set_metadata(&self, value: Rights) {
68 let key = DictKey::new(<Self as Metadata<Rights>>::KEY)
69 .expect("dict key creation failed unexpectedly");
70 match self.insert(key, Capability::Data(Data::Uint64(value.into()))) {
71 Ok(()) | Err(fsandbox::CapabilityStoreError::ItemAlreadyExists) => (),
76 Err(e) => panic!("unexpected error variant returned from Dict::insert(): {e:?}"),
78 }
79 }
80
81 fn get_metadata(&self) -> Option<Rights> {
82 let key = DictKey::new(<Self as Metadata<Rights>>::KEY)
83 .expect("dict key creation failed unexpectedly");
84 let capability = self.get(&key).ok()??;
85 let rights = match capability {
86 Capability::Data(Data::Uint64(rights)) => fio::Operations::from_bits(rights)?,
87 _ => None?,
88 };
89 Some(Rights::from(rights))
90 }
91}
92
93pub fn protocol_metadata(availability: cm_types::Availability) -> sandbox::Dict {
95 let metadata = sandbox::Dict::new();
96 metadata
97 .insert(
98 cm_types::Name::new(METADATA_KEY_TYPE).unwrap(),
99 sandbox::Capability::Data(sandbox::Data::String(String::from(TYPE_PROTOCOL))),
100 )
101 .unwrap();
102 metadata.set_metadata(availability);
103 metadata
104}
105
106pub fn dictionary_metadata(availability: cm_types::Availability) -> sandbox::Dict {
108 let metadata = sandbox::Dict::new();
109 metadata
110 .insert(
111 cm_types::Name::new(METADATA_KEY_TYPE).unwrap(),
112 sandbox::Capability::Data(sandbox::Data::String(String::from(TYPE_DICTIONARY))),
113 )
114 .unwrap();
115 metadata.set_metadata(availability);
116 metadata
117}
118
119pub fn config_metadata(availability: cm_types::Availability) -> sandbox::Dict {
121 let metadata = sandbox::Dict::new();
122 metadata
123 .insert(
124 cm_types::Name::new(METADATA_KEY_TYPE).unwrap(),
125 sandbox::Capability::Data(sandbox::Data::String(String::from(TYPE_CONFIG))),
126 )
127 .unwrap();
128 metadata.set_metadata(availability);
129 metadata
130}
131
132pub fn runner_metadata(availability: cm_types::Availability) -> sandbox::Dict {
134 let metadata = sandbox::Dict::new();
135 metadata
136 .insert(
137 cm_types::Name::new(METADATA_KEY_TYPE).unwrap(),
138 sandbox::Capability::Data(sandbox::Data::String(
139 cm_rust::CapabilityTypeName::Runner.to_string(),
140 )),
141 )
142 .unwrap();
143 metadata.set_metadata(availability);
144 metadata
145}
146
147pub fn resolver_metadata(availability: cm_types::Availability) -> sandbox::Dict {
149 let metadata = sandbox::Dict::new();
150 metadata
151 .insert(
152 cm_types::Name::new(METADATA_KEY_TYPE).unwrap(),
153 sandbox::Capability::Data(sandbox::Data::String(
154 cm_rust::CapabilityTypeName::Resolver.to_string(),
155 )),
156 )
157 .unwrap();
158 metadata.set_metadata(availability);
159 metadata
160}
161
162pub fn service_metadata(availability: cm_types::Availability) -> sandbox::Dict {
164 let metadata = sandbox::Dict::new();
165 metadata
166 .insert(
167 cm_types::Name::new(METADATA_KEY_TYPE).unwrap(),
168 sandbox::Capability::Data(sandbox::Data::String(
169 cm_rust::CapabilityTypeName::Service.to_string(),
170 )),
171 )
172 .unwrap();
173 metadata.set_metadata(availability);
174 metadata
175}