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(&mut serde_json::Deserializer::from_str(partial)).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/// struct CustomType(i32);
71///
72/// impl Overwrite for CustomType {
73///     fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
74///     where
75///         D: Deserializer<'de>,
76///     {
77///         *self = CustomType::deserialize(d)?;
78///         Ok(())
79///     }
80/// }
81/// ```
82pub trait Overwrite {
83    /// Overwrites the current value with data from a deserializer.
84    ///
85    /// For primitive types and collections, this completely replaces the value.
86    /// For structs with derived `Overwrite`, only fields present in the deserializer
87    /// are updated.
88    ///
89    /// # Arguments
90    ///
91    /// * `d` - A deserializer containing the data to overwrite with
92    ///
93    /// # Errors
94    ///
95    /// Returns a deserialization error if the input data is invalid for the type.
96    ///
97    /// # Examples
98    ///
99    /// ```rust
100    /// use serde_extensions::Overwrite;
101    ///
102    /// let mut value = 42;
103    /// value.overwrite(&mut serde_json::Deserializer::from_str("100")).unwrap();
104    /// assert_eq!(value, 100);
105    /// ```
106    fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
107    where
108        D: serde::Deserializer<'de>;
109}
110
111// Blanket implementations for common types that should just be replaced, not merged
112macro_rules! impl_overwrite_replace {
113    ($($t:ty),*) => {
114        $(
115            impl Overwrite for $t {
116                fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
117                where
118                    D: serde::Deserializer<'de>,
119                {
120                    *self = Deserialize::deserialize(d)?;
121                    Ok(())
122                }
123            }
124        )*
125    };
126}
127
128// Implement Overwrite for common primitive and standard library types
129impl_overwrite_replace!(
130    bool, i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, f64, String, char, usize, isize
131);
132
133// Implement for Option<T> where T: Overwrite
134impl<T> Overwrite for Option<T>
135where
136    T: for<'de> Deserialize<'de>,
137{
138    fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
139    where
140        D: serde::Deserializer<'de>,
141    {
142        *self = Deserialize::deserialize(d)?;
143        Ok(())
144    }
145}
146
147// Implement for Vec<T> where T: Overwrite
148impl<T> Overwrite for Vec<T>
149where
150    T: for<'de> Deserialize<'de>,
151{
152    fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
153    where
154        D: serde::Deserializer<'de>,
155    {
156        *self = Deserialize::deserialize(d)?;
157        Ok(())
158    }
159}
160
161// Implement for types from common crates
162impl Overwrite for std::path::PathBuf {
163    fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
164    where
165        D: serde::Deserializer<'de>,
166    {
167        *self = Deserialize::deserialize(d)?;
168        Ok(())
169    }
170}
171
172impl<K, V> Overwrite for std::collections::HashMap<K, V>
173where
174    K: for<'de> Deserialize<'de> + std::hash::Hash + Eq,
175    V: for<'de> Deserialize<'de>,
176{
177    fn overwrite<'de, D>(&mut self, d: D) -> Result<(), D::Error>
178    where
179        D: serde::Deserializer<'de>,
180    {
181        *self = Deserialize::deserialize(d)?;
182        Ok(())
183    }
184}