statime_config/tree/
section.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2
3use crate::{
4 ConfigError,
5 tree::{
6 empty::EffectivelyUnset,
7 merge::{Merge, MergeContext, OriginId},
8 partial_value::PartialValue,
9 path::ConfigPath,
10 },
11};
12
13#[derive(Default, Debug, Clone, PartialEq, Eq)]
15pub enum Section<T> {
16 #[default]
17 Unset,
18 Set(T),
19}
20
21impl<T> Section<T> {
22 pub fn is_unset(&self) -> bool {
23 matches!(self, Section::Unset)
24 }
25}
26
27impl<'de, T> Deserialize<'de> for Section<T>
28where
29 T: Deserialize<'de>,
30{
31 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
32 where
33 D: Deserializer<'de>,
34 {
35 T::deserialize(deserializer).map(Self::Set)
36 }
37}
38
39impl<T> Serialize for Section<T>
40where
41 T: Serialize,
42{
43 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
44 where
45 S: Serializer,
46 {
47 match self {
48 Self::Set(value) => value.serialize(serializer),
49 Self::Unset => serializer.serialize_none(),
51 }
52 }
53}
54
55impl<T> EffectivelyUnset for Section<T>
58where
59 T: EffectivelyUnset,
60{
61 fn is_effectively_unset(&self) -> bool {
62 match self {
63 Section::Unset => true,
64 Section::Set(value) => value.is_effectively_unset(),
65 }
66 }
67}
68
69impl<T> PartialValue for Section<T>
70where
71 T: PartialValue + Default,
72{
73 type Resolved = T::Resolved;
74
75 fn attribute(&mut self, origin: OriginId) {
77 if let Section::Set(value) = self {
78 value.attribute(origin);
79 }
80 }
81
82 fn apply_defaults(&mut self) {
86 if self.is_unset() {
87 *self = Section::Set(T::default());
88 }
89
90 if let Section::Set(value) = self {
91 value.apply_defaults();
92 }
93 }
94
95 fn resolve(self, path: &mut ConfigPath) -> Result<Self::Resolved, ConfigError> {
99 match self {
100 Section::Set(value) => value.resolve(path),
101 Section::Unset => T::default().resolve(path),
102 }
103 }
104}
105
106impl<T> Merge for Section<T>
110where
111 T: Merge,
112{
113 fn merge(&mut self, incoming: Self, context: &mut MergeContext<'_>) -> Result<(), ConfigError> {
114 let Section::Set(incoming) = incoming else {
115 return Ok(());
116 };
117
118 match self {
119 Section::Set(existing) => existing.merge(incoming, context),
120 Section::Unset => {
121 *self = Section::Set(incoming);
122 Ok(())
123 }
124 }
125 }
126}