statime_config/tree/configurable.rs
1use crate::{
2 Merge, PartialValue,
3 tree::{EffectivelyUnset, setting::Setting},
4};
5
6/// Relates a configuration type to how it is represented while a configuration
7/// is still being loaded.
8///
9/// This is what lets every field of a partial struct be written the same way,
10/// as `<FieldType as Configurable>::Node`, without knowing whether the field
11/// holds an atomic value or a nested struct: the type itself answers that.
12pub trait Configurable {
13 /// How this type is represented before defaults are applied.
14 type Partial: PartialValue<Resolved = Self>;
15
16 /// How a field of this type is stored in the partial struct holding it.
17 /// Atomic values are stored in a [`Setting`], nested structs in a
18 /// [`Section`](crate::tree::section::Section).
19 type Node: PartialValue
20 + Default
21 + EffectivelyUnset
22 + Merge
23 + serde::Serialize
24 + for<'a> serde::Deserialize<'a>;
25}
26
27/// A vector is atomic for merging, so it is stored in a single setting, while
28/// its elements stay partial so that they can be defaulted individually.
29impl<T> Configurable for Vec<T>
30where
31 T: Configurable,
32 <T as Configurable>::Partial: serde::Serialize + for<'a> serde::Deserialize<'a>,
33{
34 type Partial = Vec<T::Partial>;
35 type Node = Setting<Vec<T::Partial>>;
36}