statime_config/tree/
enum_section.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2
3use crate::{
4 ConfigError, ConfigPath, Merge, MergeContext, OriginId, PartialValue, tree::EffectivelyUnset,
5};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum EnumSection<T> {
11 Unset,
12 Set(T),
13}
14
15#[allow(clippy::derivable_impls, reason = "Want this even when T not Default")]
17impl<T> Default for EnumSection<T> {
18 fn default() -> Self {
19 Self::Unset
20 }
21}
22
23impl<T> EnumSection<T> {
24 pub fn is_unset(&self) -> bool {
25 matches!(self, EnumSection::Unset)
26 }
27}
28
29impl<'de, T> Deserialize<'de> for EnumSection<T>
30where
31 T: Deserialize<'de>,
32{
33 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
34 where
35 D: Deserializer<'de>,
36 {
37 T::deserialize(deserializer).map(Self::Set)
38 }
39}
40
41impl<T> Serialize for EnumSection<T>
42where
43 T: Serialize,
44{
45 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
46 where
47 S: Serializer,
48 {
49 match self {
50 Self::Set(value) => value.serialize(serializer),
51 Self::Unset => serializer.serialize_none(),
53 }
54 }
55}
56
57impl<T> EffectivelyUnset for EnumSection<T> {
60 fn is_effectively_unset(&self) -> bool {
61 matches!(self, EnumSection::Unset)
62 }
63}
64
65impl<T> PartialValue for EnumSection<T>
66where
67 T: PartialValue,
68{
69 type Resolved = T::Resolved;
70
71 fn attribute(&mut self, origin: OriginId) {
73 if let EnumSection::Set(value) = self {
74 value.attribute(origin);
75 }
76 }
77
78 fn apply_defaults(&mut self) {
82 if let EnumSection::Set(value) = self {
83 value.apply_defaults();
84 }
85 }
86
87 fn resolve(self, path: &mut ConfigPath) -> Result<Self::Resolved, ConfigError> {
91 match self {
92 EnumSection::Set(value) => value.resolve(path),
93 EnumSection::Unset => Err(ConfigError::MissingRequiredValue {
94 position: path.clone(),
95 }),
96 }
97 }
98}
99
100impl<T> Merge for EnumSection<T>
104where
105 T: Merge,
106{
107 fn merge(&mut self, incoming: Self, context: &mut MergeContext<'_>) -> Result<(), ConfigError> {
108 let EnumSection::Set(incoming) = incoming else {
109 return Ok(());
110 };
111
112 match self {
113 EnumSection::Set(existing) => existing.merge(incoming, context),
114 EnumSection::Unset => {
115 *self = EnumSection::Set(incoming);
116 Ok(())
117 }
118 }
119 }
120}