use crate::ser::selective::Selective;
use crate::spec::MaskSpec;
use crate::trie::MaskTrie;
use crate::validate::validate_mask;
use crate::{FieldMask, FieldMaskError};
use serde::ser::Error;
use serde::{Serialize, Serializer};
#[derive(Clone, Debug)]
pub struct Masked<T> {
value: T,
mask: FieldMask,
}
impl<T> Masked<T> {
pub fn new(value: T, mask: FieldMask) -> Self {
Self { value, mask }
}
pub fn into_inner(self) -> T {
self.value
}
pub fn mask(&self) -> &FieldMask {
&self.mask
}
pub fn contains_exact(&self, path: &str) -> Result<bool, FieldMaskError>
where
T: MaskSpec,
{
self.mask.contains_exact::<T>(path)
}
pub fn intersects(&self, path: &str) -> Result<bool, FieldMaskError>
where
T: MaskSpec,
{
self.mask.intersects::<T>(path)
}
}
impl<T> Serialize for Masked<T>
where
T: Serialize + MaskSpec,
{
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
if self.mask.is_all() || self.mask.is_empty() {
return self.value.serialize(serializer);
}
validate_mask(&self.mask, T::mask_spec()).map_err(|e| Error::custom(e.to_string()))?;
let trie = MaskTrie::new(&self.mask);
let gate = Selective {
ser: serializer,
trie: &trie,
spec: T::mask_spec(),
include_all: trie.terminal,
};
self.value
.serialize(gate)
.map_err(|e| Error::custom(e.to_string()))
}
}