serde_diff/
config.rs

1use crate::{Apply, Diff, FieldPathMode, SerdeDiff};
2use serde::{de, Serialize, Serializer};
3use std::cell::Cell;
4
5/// Configures creation of `Apply` and `Diff`
6///
7/// # Examples
8///
9/// ```rust
10/// use serde_diff::{SerdeDiff, Config, FieldPathMode};
11/// use serde::{Serialize, Deserialize};
12/// #[derive(SerdeDiff, Serialize, Deserialize, PartialEq)]
13/// struct Test {
14///     a: i32,
15/// }
16/// let diff = Config::new()
17///     .with_field_path_mode(FieldPathMode::Index)
18///     .serializable_diff(&Test { a: 3 }, &Test { a: 5 });
19/// ```
20pub struct Config {
21    field_path_mode: FieldPathMode,
22}
23
24impl Default for Config {
25    fn default() -> Self {
26        Self {
27            field_path_mode: FieldPathMode::Name,
28        }
29    }
30}
31
32impl Config {
33    /// Creates a `Config` with default values
34    pub fn new() -> Self {
35        <Self as Default>::default()
36    }
37
38    /// Sets the `FieldPathMode` to use when serializing a Diff
39    pub fn with_field_path_mode(mut self, mode: FieldPathMode) -> Self {
40        self.field_path_mode = mode;
41        self
42    }
43
44    /// Create a serializable Diff, which when serialized will write the differences between the old
45    /// and new value into the serializer in the form of a sequence of diff commands
46    pub fn serializable_diff<'a, 'b, T: SerdeDiff + 'a + 'b>(
47        self,
48        old: &'a T,
49        new: &'b T,
50    ) -> Diff<'a, 'b, T> {
51        Diff {
52            old,
53            new,
54            field_path_mode: self.field_path_mode,
55            has_changes: Cell::new(false),
56        }
57    }
58
59    /// Writes the differences between the old and new value into the given serializer in the form
60    /// of a sequence of diff commands
61    pub fn diff<'a, 'b, S: Serializer, T: SerdeDiff + 'a + 'b>(
62        self,
63        serializer: S,
64        old: &'a T,
65        new: &'b T,
66    ) -> Result<S::Ok, S::Error> {
67        self.serializable_diff(old, new).serialize(serializer)
68    }
69
70    /// Create a deserializable Apply, where the given target will be changed when the resulting
71    /// Apply struct is deserialized
72    pub fn deserializable_apply<'a, T: SerdeDiff>(self, target: &'a mut T) -> Apply<'a, T> {
73        Apply { target }
74    }
75
76    /// Applies a sequence of diff commands to the target, as read by the deserializer
77    pub fn apply<'de, D, T: SerdeDiff>(
78        self,
79        deserializer: D,
80        target: &mut T,
81    ) -> Result<(), <D as de::Deserializer<'de>>::Error>
82    where
83        D: de::Deserializer<'de>,
84    {
85        deserializer.deserialize_seq(self.deserializable_apply(target))
86    }
87}