serde_partial/
filter.rs

1//! Field filtering
2
3use core::{fmt, marker::PhantomData};
4
5use crate::{Field, SerializePartial};
6
7/// Trait implemented by types which can be used to filter the serializable fields of another type.
8pub trait SerializeFilter<T: ?Sized> {
9    /// Returns whether the specified field should be skipped.
10    fn skip(&self, field: Field<'_, T>) -> bool;
11
12    /// Returns the number of fields which will be serialized given the total field count.
13    fn filtered_len(&self, len: Option<usize>) -> Option<usize>;
14}
15
16/// A [`SerializeFilter`] which inverts the behavior of the filter it wraps.
17pub struct InverseFilter<'a, T, F = <T as SerializePartial<'a>>::Filter>
18where
19    T: ?Sized + SerializePartial<'a>,
20{
21    filter: F,
22    _ty: PhantomData<&'a T>,
23}
24
25impl<'a, T, F> SerializeFilter<T> for InverseFilter<'a, T, F>
26where
27    T: ?Sized + SerializePartial<'a>,
28    F: SerializeFilter<T>,
29{
30    fn skip(&self, field: Field<'_, T>) -> bool {
31        !self.filter.skip(field)
32    }
33
34    fn filtered_len(&self, len: Option<usize>) -> Option<usize> {
35        match (len, self.filter.filtered_len(len)) {
36            (Some(len), Some(filtered_len)) => Some(len - filtered_len),
37            _ => None,
38        }
39    }
40}
41
42impl<'a, T, F> InverseFilter<'a, T, F>
43where
44    T: ?Sized + SerializePartial<'a>,
45    F: SerializeFilter<T>,
46{
47    /// Creates a filter which inverts the behavior of the provided one.
48    pub fn new(filter: F) -> Self {
49        Self {
50            filter,
51            _ty: PhantomData,
52        }
53    }
54}
55
56impl<'a, T, F> Clone for InverseFilter<'a, T, F>
57where
58    T: ?Sized + SerializePartial<'a>,
59    F: Clone,
60{
61    fn clone(&self) -> Self {
62        Self {
63            filter: self.filter.clone(),
64            _ty: PhantomData,
65        }
66    }
67}
68impl<'a, T, F> Copy for InverseFilter<'a, T, F>
69where
70    T: ?Sized + SerializePartial<'a>,
71    F: Copy,
72{
73}
74
75impl<'a, T, F> fmt::Debug for InverseFilter<'a, T, F>
76where
77    T: ?Sized + SerializePartial<'a>,
78    F: fmt::Debug,
79{
80    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81        f.debug_tuple("InverseFilter").field(&self.filter).finish()
82    }
83}