#![no_std]
#![doc = include_str!("../README.md")]
#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
use core::{cmp, fmt, hash, marker::PhantomData};
use serde::ser::{Serialize, Serializer};
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "alloc", path = "alloc.rs")]
mod feature_alloc;
#[cfg(feature = "std")]
#[cfg_attr(feature = "std", path = "std.rs")]
mod feature_std;
#[path = "map.rs"]
mod serde_map;
#[path = "struct.rs"]
mod serde_struct;
pub mod filter;
pub use filter::SerializeFilter;
pub use serde_partial_macro::SerializePartial;
pub trait SerializePartial<'a>: Serialize {
type Fields: 'a;
type Filter: SerializeFilter<Self> + 'a;
fn with_fields<F, I>(&'a self, select: F) -> Partial<'a, Self>
where
F: FnOnce(Self::Fields) -> I,
I: IntoIterator<Item = Field<'a, Self>>;
fn without_fields<F, I>(
&'a self,
select: F,
) -> Partial<'a, Self, filter::InverseFilter<'a, Self>>
where
F: FnOnce(Self::Fields) -> I,
I: IntoIterator<Item = Field<'a, Self>>,
{
let Partial { value, filter } = self.with_fields(select);
Partial {
value,
filter: filter::InverseFilter::new(filter),
}
}
}
#[derive(Debug)]
pub struct Partial<'a, T, F = <T as SerializePartial<'a>>::Filter>
where
T: ?Sized + SerializePartial<'a>,
{
pub value: &'a T,
pub filter: F,
}
#[repr(transparent)]
pub struct Field<'a, T: ?Sized> {
name: &'a str,
_ty: PhantomData<T>,
}
impl<'a, T, F> Clone for Partial<'a, T, F>
where
T: ?Sized + SerializePartial<'a>,
F: Clone,
{
fn clone(&self) -> Self {
Self {
value: self.value,
filter: self.filter.clone(),
}
}
}
impl<'a, T, F> Copy for Partial<'a, T, F>
where
T: ?Sized + SerializePartial<'a>,
F: Copy,
{
}
impl<'a, T: ?Sized> Field<'a, T> {
pub const fn new(name: &'a str) -> Self {
Self {
name,
_ty: PhantomData,
}
}
pub const fn name(&self) -> &'a str {
self.name
}
}
impl<T: ?Sized> Clone for Field<'_, T> {
fn clone(&self) -> Self {
Self {
name: self.name,
_ty: PhantomData,
}
}
}
impl<T: ?Sized> Copy for Field<'_, T> {}
impl<T: ?Sized> fmt::Debug for Field<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Field")
.field("name", &self.name)
.field("container", &core::any::type_name::<T>())
.finish()
}
}
impl<T: ?Sized> PartialEq for Field<'_, T> {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
impl<T: ?Sized> Eq for Field<'_, T> {}
impl<T: ?Sized> hash::Hash for Field<'_, T> {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.name.hash(state);
}
}
impl<T: ?Sized> PartialOrd for Field<'_, T> {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
self.name.partial_cmp(other.name)
}
}
impl<T: ?Sized> Ord for Field<'_, T> {
fn cmp(&self, other: &Self) -> cmp::Ordering {
self.name.cmp(other.name)
}
}
impl<T, F> Serialize for Partial<'_, T, F>
where
T: ?Sized + for<'a> SerializePartial<'a>,
F: SerializeFilter<T>,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let serializer = PartialSerializer {
s: serializer,
filter: &self.filter,
_ty: PhantomData,
};
self.value.serialize(serializer)
}
}
struct PartialSerializer<'a, S, T, F>
where
S: Serializer,
T: ?Sized,
{
s: S,
filter: &'a F,
_ty: PhantomData<T>,
}
impl<'a, S, T, F> Serializer for PartialSerializer<'a, S, T, F>
where
S: Serializer,
T: ?Sized + for<'p> SerializePartial<'p>,
F: SerializeFilter<T>,
{
type Ok = S::Ok;
type Error = S::Error;
type SerializeStruct = serde_struct::PartialSerializeStruct<'a, S, T, F>;
type SerializeMap = serde_map::PartialSerializeMap<'a, S, T, F>;
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
let PartialSerializer { s, filter, _ty } = self;
let len = filter.filtered_len(Some(len)).unwrap_or(len);
let ss = s.serialize_struct(name, len)?;
Ok(Self::SerializeStruct { ss, filter, _ty })
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
let PartialSerializer { s, filter, _ty } = self;
let len = filter.filtered_len(len).or(len);
let sm = s.serialize_map(len)?;
Ok(Self::SerializeMap { sm, filter, _ty })
}
type SerializeSeq = S::SerializeSeq;
type SerializeTuple = S::SerializeTuple;
type SerializeTupleStruct = S::SerializeTupleStruct;
type SerializeTupleVariant = S::SerializeTupleVariant;
type SerializeStructVariant = S::SerializeStructVariant;
fn is_human_readable(&self) -> bool {
self.s.is_human_readable()
}
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
self.s.serialize_bool(v)
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
self.s.serialize_i8(v)
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
self.s.serialize_i16(v)
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
self.s.serialize_i32(v)
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
self.s.serialize_i64(v)
}
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
self.s.serialize_i128(v)
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
self.s.serialize_u8(v)
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
self.s.serialize_u16(v)
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
self.s.serialize_u32(v)
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
self.s.serialize_u64(v)
}
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
self.s.serialize_u128(v)
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
self.s.serialize_f32(v)
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
self.s.serialize_f64(v)
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
self.s.serialize_char(v)
}
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
self.s.serialize_str(v)
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
self.s.serialize_bytes(v)
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
self.s.serialize_none()
}
fn serialize_some<TT: ?Sized>(self, value: &TT) -> Result<Self::Ok, Self::Error>
where
TT: Serialize,
{
self.s.serialize_some(value)
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
self.s.serialize_unit()
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
self.s.serialize_unit_struct(name)
}
fn serialize_unit_variant(
self,
name: &'static str,
index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
self.s.serialize_unit_variant(name, index, variant)
}
fn serialize_newtype_struct<TT: ?Sized>(
self,
name: &'static str,
value: &TT,
) -> Result<Self::Ok, Self::Error>
where
TT: Serialize,
{
self.s.serialize_newtype_struct(name, value)
}
fn serialize_newtype_variant<TT: ?Sized>(
self,
name: &'static str,
index: u32,
variant: &'static str,
value: &TT,
) -> Result<Self::Ok, Self::Error>
where
TT: Serialize,
{
self.s
.serialize_newtype_variant(name, index, variant, value)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
self.s.serialize_seq(len)
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
self.s.serialize_tuple(len)
}
fn serialize_tuple_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
self.s.serialize_tuple_struct(name, len)
}
fn serialize_tuple_variant(
self,
name: &'static str,
index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
self.s.serialize_tuple_variant(name, index, variant, len)
}
fn serialize_struct_variant(
self,
name: &'static str,
index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
self.s.serialize_struct_variant(name, index, variant, len)
}
fn collect_str<TT: ?Sized>(self, value: &TT) -> Result<Self::Ok, Self::Error>
where
TT: fmt::Display,
{
self.s.collect_str(value)
}
fn collect_seq<I>(self, iter: I) -> Result<Self::Ok, Self::Error>
where
I: IntoIterator,
<I as IntoIterator>::Item: Serialize,
{
self.s.collect_seq(iter)
}
}