1use crate::accessibility::types::AccessibilityInfo;
17use crate::audio::types::AudioInfo;
18use crate::display::types::DisplayInfo;
19use crate::do_not_disturb::types::DoNotDisturbInfo;
20use crate::factory_reset::types::FactoryResetInfo;
21use crate::ingress::fidl;
22use crate::input::types::InputInfo;
23use crate::intl::types::IntlInfo;
24use crate::keyboard::types::KeyboardInfo;
25use crate::light::types::LightInfo;
26use crate::night_mode::types::NightModeInfo;
27use crate::privacy::types::PrivacyInfo;
28use crate::setup::types::SetupInfo;
29#[cfg(test)]
30use serde::Deserialize;
31use serde::Serialize;
32use std::collections::HashSet;
33
34#[derive(PartialEq, Debug, Eq, Hash, Clone, Copy, Serialize)]
36pub enum SettingType {
37 #[cfg(test)]
39 Unknown,
40 Accessibility,
41 Audio,
42 Display,
43 DoNotDisturb,
44 FactoryReset,
45 Input,
46 Intl,
47 Keyboard,
48 Light,
49 NightMode,
50 Privacy,
51 Setup,
52}
53
54#[derive(PartialEq, Debug, Eq, Hash, Clone, Copy)]
58pub enum Entity {
59 Handler(SettingType),
61}
62
63#[derive(PartialEq, Debug, Eq, Hash, Clone, Copy)]
68pub(crate) enum Dependency {
69 Entity(Entity),
71}
72
73impl Dependency {
74 pub(crate) fn is_fulfilled(&self, entities: &HashSet<Entity>) -> bool {
77 match self {
78 Dependency::Entity(entity) => entities.contains(entity),
79 }
80 }
81}
82
83#[macro_export]
87macro_rules! generate_inspect_with_info {
88 ($(#[$metas:meta])* pub enum $name:ident {
89 $(
90 $(#[doc = $str:expr])*
91 $(#[cfg($test:meta)])?
92 $variant:ident ( $data:ty )
93 ),* $(,)?
94 }
95 ) => {
96 $(#[$metas])*
97 pub enum $name {
98 $(
99 $(#[doc = $str])*
100 $(#[cfg($test)])?
101 $variant($data),
102 )*
103 }
104
105 impl $name {
106 pub(crate) fn for_inspect(&self) -> (&'static str, String) {
108 match self {
109 $(
110 $(#[cfg($test)])?
111 $name::$variant(info) => (stringify!($variant), format!("{:?}", info)),
112 )*
113 }
114 }
115 }
116 };
117}
118
119generate_inspect_with_info! {
120 #[derive(PartialEq, Debug, Clone)]
122 pub enum SettingInfo {
123 #[cfg(test)]
125 Unknown(UnknownInfo),
126 Accessibility(AccessibilityInfo),
127 Audio(AudioInfo),
128 Brightness(DisplayInfo),
129 FactoryReset(FactoryResetInfo),
130 Light(LightInfo),
131 DoNotDisturb(DoNotDisturbInfo),
132 Input(InputInfo),
133 Intl(IntlInfo),
134 Keyboard(KeyboardInfo),
135 NightMode(NightModeInfo),
136 Privacy(PrivacyInfo),
137 Setup(SetupInfo),
138 }
139}
140
141pub(crate) trait HasSettingType {
142 const SETTING_TYPE: SettingType;
143}
144
145macro_rules! conversion_impls {
146 ($($(#[cfg($test:meta)])? $variant:ident($info_ty:ty) => $ty_variant:ident ),+ $(,)?) => {
147 $(
148 $(#[cfg($test)])?
149 impl HasSettingType for $info_ty {
150 const SETTING_TYPE: SettingType = SettingType::$ty_variant;
151 }
152
153 $(#[cfg($test)])?
154 impl TryFrom<SettingInfo> for $info_ty {
155 type Error = ();
156
157 fn try_from(setting_info: SettingInfo) -> Result<Self, ()> {
158 match setting_info {
159 SettingInfo::$variant(info) => Ok(info),
160 _ => Err(()),
161 }
162 }
163 }
164 )+
165 }
166}
167
168conversion_impls! {
169 #[cfg(test)] Unknown(UnknownInfo) => Unknown,
170 Accessibility(AccessibilityInfo) => Accessibility,
171 Audio(AudioInfo) => Audio,
172 Brightness(DisplayInfo) => Display,
173 FactoryReset(FactoryResetInfo) => FactoryReset,
174 Light(LightInfo) => Light,
175 DoNotDisturb(DoNotDisturbInfo) => DoNotDisturb,
176 Input(InputInfo) => Input,
177 Intl(IntlInfo) => Intl,
178 Keyboard(KeyboardInfo) => Keyboard,
179 NightMode(NightModeInfo) => NightMode,
180 Privacy(PrivacyInfo) => Privacy,
181 Setup(SetupInfo) => Setup,
182}
183
184impl From<&SettingInfo> for SettingType {
185 fn from(info: &SettingInfo) -> SettingType {
186 match info {
187 #[cfg(test)]
188 SettingInfo::Unknown(_) => SettingType::Unknown,
189 SettingInfo::Accessibility(_) => SettingType::Accessibility,
190 SettingInfo::Audio(_) => SettingType::Audio,
191 SettingInfo::Brightness(_) => SettingType::Display,
192 SettingInfo::DoNotDisturb(_) => SettingType::DoNotDisturb,
193 SettingInfo::FactoryReset(_) => SettingType::FactoryReset,
194 SettingInfo::Input(_) => SettingType::Input,
195 SettingInfo::Intl(_) => SettingType::Intl,
196 SettingInfo::Keyboard(_) => SettingType::Keyboard,
197 SettingInfo::Light(_) => SettingType::Light,
198 SettingInfo::NightMode(_) => SettingType::NightMode,
199 SettingInfo::Privacy(_) => SettingType::Privacy,
200 SettingInfo::Setup(_) => SettingType::Setup,
201 }
202 }
203}
204
205#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
208#[cfg(test)]
209#[derive(Default)]
210pub struct UnknownInfo(pub bool);
211
212pub(crate) trait Merge<Other = Self> {
214 fn merge(&self, other: Other) -> Self;
217}
218
219pub fn get_default_interfaces() -> HashSet<fidl::InterfaceSpec> {
221 [
222 fidl::InterfaceSpec::Accessibility,
223 fidl::InterfaceSpec::Intl,
224 fidl::InterfaceSpec::Privacy,
225 fidl::InterfaceSpec::Setup,
226 ]
227 .into()
228}
229
230#[cfg(test)]
233pub(crate) fn get_all_setting_types() -> HashSet<SettingType> {
234 [
235 SettingType::Accessibility,
236 SettingType::Audio,
237 SettingType::Display,
238 SettingType::DoNotDisturb,
239 SettingType::FactoryReset,
240 SettingType::Input,
241 SettingType::Intl,
242 SettingType::Keyboard,
243 SettingType::Light,
244 SettingType::NightMode,
245 SettingType::Privacy,
246 SettingType::Setup,
247 ]
248 .into()
249}
250
251#[cfg(test)]
252mod testing {
253 use settings_storage::device_storage::DeviceStorageCompatible;
254 use settings_storage::storage_factory::NoneT;
255
256 use super::{SettingInfo, UnknownInfo};
257
258 impl DeviceStorageCompatible for UnknownInfo {
259 type Loader = NoneT;
260 const KEY: &'static str = "unknown_info";
261 }
262
263 impl From<UnknownInfo> for SettingInfo {
264 fn from(info: UnknownInfo) -> SettingInfo {
265 SettingInfo::Unknown(info)
266 }
267 }
268}
269
270#[cfg(test)]
271mod tests {
272 use super::*;
273
274 #[allow(clippy::bool_assert_comparison)]
275 #[fuchsia::test]
276 fn test_dependency_fulfillment() {
277 let target_entity = Entity::Handler(SettingType::Unknown);
278 let dependency = Dependency::Entity(target_entity);
279 let mut available_entities = HashSet::new();
280
281 assert_eq!(dependency.is_fulfilled(&available_entities), false);
283
284 let _ = available_entities.insert(Entity::Handler(SettingType::FactoryReset));
286 assert_eq!(dependency.is_fulfilled(&available_entities), false);
287
288 let _ = available_entities.insert(target_entity);
290 assert!(dependency.is_fulfilled(&available_entities));
291 }
292}