Skip to main content

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}