serde_extensions/lib.rs
1use serde::Deserialize;
2pub use serde_extensions_derive::*;
3pub use serde_value;
4
5/// A trait for selectively overwriting fields in a struct from a deserializer.
6///
7/// The `Overwrite` trait provides a mechanism to update existing values in a struct
8/// by deserializing only the fields present in the input data, leaving other fields
9/// unchanged. This is particularly useful for configuration merging, partial updates,
10/// and layered settings where you want to apply defaults first and then override
11/// specific values.
12///
13/// # Behavior
14///
15/// - For primitive types and most standard library types, `overwrite` completely
16/// replaces the existing value with the deserialized value.
17/// - For structs that derive `Overwrite` (using `#[derive(Overwrite)]`), only the
18/// fields present in the input are updated, while absent fields retain their
19/// current values.
20///
21/// # Examples
22///
23/// ```rust
24/// use serde::Deserialize;
25/// use serde_extensions::Overwrite;
26///
27/// #[derive(Deserialize, Overwrite)]
28/// struct Config {
29/// host: String,
30/// port: u16,
31/// debug: bool,
32/// }
33///
34/// let mut config = Config {
35/// host: "localhost".to_string(),
36/// port: 8080,
37/// debug: false,
38/// };
39///
40/// // Overwrite only the port, leaving host and debug unchanged
41/// let partial = r#"port=3000"#;
42/// config.overwrite(toml::from_str::<toml::Value>(partial).unwrap()).unwrap();
43///
44/// assert_eq!(config.host, "localhost");
45/// assert_eq!(config.port, 3000);
46/// assert_eq!(config.debug, false);
47/// ```
48///
49/// # Implementing for Custom Types
50///
51/// For structs, you can derive `Overwrite` automatically:
52///
53/// ```rust
54/// use serde_extensions::Overwrite;
55///
56/// #[derive(Overwrite)]
57/// struct MyStruct {
58/// field1: String,
59/// field2: i32,
60/// }
61/// ```
62///
63/// For other types, implement the trait manually. Types that should be completely
64/// replaced (rather than merged) should deserialize a new value and assign it:
65///
66/// ```rust
67/// use serde::{Deserialize, Deserializer};
68/// use serde_extensions::Overwrite;
69///
70/// #[derive(Deserialize)]
71/// struct CustomType(i32);
72///
73/// impl Overwrite for CustomType {
74/// fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
75/// where
76/// D: Deserializer<'de>,
77/// {
78/// *self = CustomType::deserialize(d)?;
79/// Ok(())
80/// }
81/// }
82/// ```
83pub trait Overwrite {
84 /// Overwrites the current value with data from a deserializer.
85 ///
86 /// For primitive types and collections, this completely replaces the value.
87 /// For structs with derived `Overwrite`, only fields present in the deserializer
88 /// are updated.
89 ///
90 /// # Arguments
91 ///
92 /// * `d` - A deserializer containing the data to overwrite with
93 ///
94 /// # Errors
95 ///
96 /// Returns a deserialization error if the input data is invalid for the type.
97 ///
98 /// # Examples
99 ///
100 /// ```rust
101 /// use serde_extensions::Overwrite;
102 ///
103 /// let mut value = 42;
104 /// let parsed_value = toml::Value::Integer(100);
105 /// value.overwrite(parsed_value).unwrap();
106 /// assert_eq!(value, 100);
107 /// ```
108 fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
109 where
110 D: serde::Deserializer<'de>;
111}
112
113// Blanket implementations for common types that should just be replaced, not merged
114macro_rules! impl_overwrite_replace {
115 ($($t:ty),*) => {
116 $(
117 impl Overwrite for $t {
118 fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
119 where
120 D: serde::Deserializer<'de>,
121 {
122 *self = Deserialize::deserialize(d)?;
123 Ok(())
124 }
125 }
126 )*
127 };
128}
129
130// Implement Overwrite for common primitive and standard library types
131impl_overwrite_replace!(
132 bool, i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, f64, String, char, usize, isize
133);
134
135// Implement for Option<T> where T: Overwrite
136impl<T> Overwrite for Option<T>
137where
138 T: for<'de> Deserialize<'de>,
139{
140 fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
141 where
142 D: serde::Deserializer<'de>,
143 {
144 *self = Deserialize::deserialize(d)?;
145 Ok(())
146 }
147}
148
149// Implement for Vec<T> where T: Overwrite
150impl<T> Overwrite for Vec<T>
151where
152 T: for<'de> Deserialize<'de>,
153{
154 fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
155 where
156 D: serde::Deserializer<'de>,
157 {
158 *self = Deserialize::deserialize(d)?;
159 Ok(())
160 }
161}
162
163// Implement for types from common crates
164impl Overwrite for std::path::PathBuf {
165 fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
166 where
167 D: serde::Deserializer<'de>,
168 {
169 *self = Deserialize::deserialize(d)?;
170 Ok(())
171 }
172}
173
174impl<K, V> Overwrite for std::collections::HashMap<K, V>
175where
176 K: for<'de> Deserialize<'de> + std::hash::Hash + Eq,
177 V: for<'de> Deserialize<'de>,
178{
179 fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
180 where
181 D: serde::Deserializer<'de>,
182 {
183 *self = Deserialize::deserialize(d)?;
184 Ok(())
185 }
186}