identity_diff/
macros.rs

1// Copyright 2020-2021 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::traits::Diff;
5
6use std::fmt::Debug;
7use std::fmt::Formatter;
8
9/// A macro to implement the `Diff` traits on primitive values and the `Debug` trait on the resulting `Diff*` types.
10/// Follows this syntax, impl_diff_on_primitives { type | DiffTypeName + TraitBounds}`
11macro_rules! impl_diff_on_primitives {
12    ($($type:ty | $diff:ident $(: $($traits:ident),+)?);* $(;)?) => {
13        $(
14            $( #[derive($($traits),+ )] )?
15            #[derive(serde::Deserialize, serde::Serialize, Default)]
16            pub struct $diff(#[doc(hidden)] pub Option<$type>);
17
18
19            impl Diff for $type {
20                type Type = $diff;
21
22                #[inline(always)]
23                fn diff(&self, other: &Self) -> crate::Result<Self::Type> {
24                    other.clone().into_diff()
25                }
26
27                #[inline(always)]
28                fn merge(&self, diff: Self::Type) -> crate::Result<Self> {
29                    Self::from_diff(diff)
30                }
31
32                #[inline(always)]
33                fn from_diff(diff: Self::Type) -> crate::Result<Self> {
34                    match diff.0 {
35                        Some(val) => Ok(val),
36                        None => Ok(Self::default()),
37                    }
38
39
40                }
41
42                #[inline(always)]
43                fn into_diff(self) -> crate::Result<Self::Type> {
44                    Ok($diff(Some(self)))
45                }
46            }
47
48
49            impl Debug for $diff {
50                fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
51                    match self.0 {
52                        None => write!(f, "{} None", stringify!($diff)),
53                        Some(val) => write!(f, "{} => {:#?}", stringify!($diff), val),
54                    }
55                }
56            }
57
58        )*
59    };
60}
61
62impl_diff_on_primitives! {
63    i8 | Diffi8: Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
64    i16 | Diffi16: Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
65    i32 | Diffi32:   Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
66    i64 | Diffi64:   Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
67    i128 | Diffi128:  Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
68    isize | DiffiSize: Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
69
70    u8 | Diffu8:    Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
71    u16 | Diffu16:   Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
72    u32 | Diffu32:   Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
73    u64 | Diffu64:   Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
74    u128 | Diffu128:  Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
75    usize | DiffuSize: Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
76
77    f32 | DiffF32:   Clone, Copy, PartialEq, PartialOrd;
78    f64  | DiffF64:   Clone, Copy, PartialEq, PartialOrd;
79    bool | Diffbool:  Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
80    char | Diffchar:  Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
81    () | Diffunit:  Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash;
82}