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;
23#[cfg(test)]
24use serde::Deserialize;
25use serde::Serialize;
26use std::collections::HashSet;
27
28#[derive(PartialEq, Debug, Eq, Hash, Clone, Copy, Serialize)]
30pub enum SettingType {
31 #[cfg(test)]
33 Unknown,
34 Accessibility,
35 Audio,
36 Display,
37 DoNotDisturb,
38 FactoryReset,
39 Input,
40 Intl,
41 Keyboard,
42 Light,
43 NightMode,
44 Privacy,
45 Setup,
46}
47
48#[derive(PartialEq, Debug, Eq, Hash, Clone, Copy)]
52pub enum Entity {
53 Handler(SettingType),
55}
56
57#[derive(PartialEq, Debug, Eq, Hash, Clone, Copy)]
62pub(crate) enum Dependency {
63 Entity(Entity),
65}
66
67impl Dependency {
68 pub(crate) fn is_fulfilled(&self, entities: &HashSet<Entity>) -> bool {
71 match self {
72 Dependency::Entity(entity) => entities.contains(entity),
73 }
74 }
75}
76
77#[macro_export]
81macro_rules! generate_inspect_with_info {
82 ($(#[$metas:meta])* pub enum $name:ident {
83 $(
84 $(#[doc = $str:expr])*
85 $(#[cfg($test:meta)])?
86 $variant:ident ( $data:ty )
87 ),* $(,)?
88 }
89 ) => {
90 $(#[$metas])*
91 pub enum $name {
92 $(
93 $(#[doc = $str])*
94 $(#[cfg($test)])?
95 $variant($data),
96 )*
97 }
98
99 impl $name {
100 pub(crate) fn for_inspect(&self) -> (&'static str, String) {
102 match self {
103 $(
104 $(#[cfg($test)])?
105 $name::$variant(info) => (stringify!($variant), format!("{:?}", info)),
106 )*
107 }
108 }
109 }
110 };
111}
112
113generate_inspect_with_info! {
114 #[derive(PartialEq, Debug, Clone)]
116 pub enum SettingInfo {
117 #[cfg(test)]
119 Unknown(UnknownInfo),
120 Accessibility(AccessibilityInfo),
121 Audio(AudioInfo),
122 Brightness(DisplayInfo),
123 FactoryReset(FactoryResetInfo),
124 DoNotDisturb(DoNotDisturbInfo),
125 Input(InputInfo),
126 }
127}
128
129pub(crate) trait HasSettingType {
130 const SETTING_TYPE: SettingType;
131}
132
133macro_rules! conversion_impls {
134 ($($(#[cfg($test:meta)])? $variant:ident($info_ty:ty) => $ty_variant:ident ),+ $(,)?) => {
135 $(
136 $(#[cfg($test)])?
137 impl HasSettingType for $info_ty {
138 const SETTING_TYPE: SettingType = SettingType::$ty_variant;
139 }
140
141 $(#[cfg($test)])?
142 impl TryFrom<SettingInfo> for $info_ty {
143 type Error = ();
144
145 fn try_from(setting_info: SettingInfo) -> Result<Self, ()> {
146 match setting_info {
147 SettingInfo::$variant(info) => Ok(info),
148 _ => Err(()),
149 }
150 }
151 }
152 )+
153 }
154}
155
156conversion_impls! {
157 #[cfg(test)] Unknown(UnknownInfo) => Unknown,
158 Accessibility(AccessibilityInfo) => Accessibility,
159 Audio(AudioInfo) => Audio,
160 Brightness(DisplayInfo) => Display,
161 FactoryReset(FactoryResetInfo) => FactoryReset,
162 DoNotDisturb(DoNotDisturbInfo) => DoNotDisturb,
163 Input(InputInfo) => Input,
164}
165
166impl From<&SettingInfo> for SettingType {
167 fn from(info: &SettingInfo) -> SettingType {
168 match info {
169 #[cfg(test)]
170 SettingInfo::Unknown(_) => SettingType::Unknown,
171 SettingInfo::Accessibility(_) => SettingType::Accessibility,
172 SettingInfo::Audio(_) => SettingType::Audio,
173 SettingInfo::Brightness(_) => SettingType::Display,
174 SettingInfo::DoNotDisturb(_) => SettingType::DoNotDisturb,
175 SettingInfo::FactoryReset(_) => SettingType::FactoryReset,
176 SettingInfo::Input(_) => SettingType::Input,
177 }
178 }
179}
180
181#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
184#[cfg(test)]
185#[derive(Default)]
186pub struct UnknownInfo(pub bool);
187
188pub(crate) trait Merge<Other = Self> {
190 fn merge(&self, other: Other) -> Self;
193}
194
195pub fn get_default_interfaces() -> HashSet<fidl::InterfaceSpec> {
197 [
198 fidl::InterfaceSpec::Accessibility,
199 fidl::InterfaceSpec::Intl,
200 fidl::InterfaceSpec::Privacy,
201 fidl::InterfaceSpec::Setup,
202 ]
203 .into()
204}
205
206#[cfg(test)]
209pub(crate) fn get_all_setting_types() -> HashSet<SettingType> {
210 [
211 SettingType::Accessibility,
212 SettingType::Audio,
213 SettingType::Display,
214 SettingType::DoNotDisturb,
215 SettingType::FactoryReset,
216 SettingType::Input,
217 SettingType::Intl,
218 SettingType::Keyboard,
219 SettingType::Light,
220 SettingType::NightMode,
221 SettingType::Privacy,
222 SettingType::Setup,
223 ]
224 .into()
225}
226
227#[cfg(test)]
228mod testing {
229 use settings_storage::device_storage::DeviceStorageCompatible;
230 use settings_storage::storage_factory::NoneT;
231
232 use super::{SettingInfo, UnknownInfo};
233
234 impl DeviceStorageCompatible for UnknownInfo {
235 type Loader = NoneT;
236 const KEY: &'static str = "unknown_info";
237 }
238
239 impl From<UnknownInfo> for SettingInfo {
240 fn from(info: UnknownInfo) -> SettingInfo {
241 SettingInfo::Unknown(info)
242 }
243 }
244}
245
246#[cfg(test)]
247mod tests {
248 use super::*;
249
250 #[allow(clippy::bool_assert_comparison)]
251 #[fuchsia::test]
252 fn test_dependency_fulfillment() {
253 let target_entity = Entity::Handler(SettingType::Unknown);
254 let dependency = Dependency::Entity(target_entity);
255 let mut available_entities = HashSet::new();
256
257 assert_eq!(dependency.is_fulfilled(&available_entities), false);
259
260 let _ = available_entities.insert(Entity::Handler(SettingType::FactoryReset));
262 assert_eq!(dependency.is_fulfilled(&available_entities), false);
263
264 let _ = available_entities.insert(target_entity);
266 assert!(dependency.is_fulfilled(&available_entities));
267 }
268}