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