Skip to main content

oanda_client/
patch.rs

1//! Distinguishes omitted fields from explicit JSON null in OANDA mutations.
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5/// A mutation field that may be left unchanged, cleared, or set.
6#[derive(Debug, Clone, PartialEq, Eq, Default)]
7pub enum Patch<T> {
8    /// Omit the field from the request.
9    #[default]
10    Unchanged,
11    /// Send JSON null to clear the existing value.
12    Clear,
13    /// Send a new value.
14    Set(T),
15}
16
17impl<T> Patch<T> {
18    /// Whether the field should be omitted when serialized as a struct field.
19    pub fn is_unchanged(&self) -> bool {
20        matches!(self, Self::Unchanged)
21    }
22}
23
24impl<T: Serialize> Serialize for Patch<T> {
25    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
26        match self {
27            Self::Unchanged | Self::Clear => serializer.serialize_none(),
28            Self::Set(value) => value.serialize(serializer),
29        }
30    }
31}
32
33impl<'de, T: Deserialize<'de>> Deserialize<'de> for Patch<T> {
34    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
35        Option::<T>::deserialize(deserializer).map(|value| match value {
36            Some(value) => Self::Set(value),
37            None => Self::Clear,
38        })
39    }
40}