use core::{
convert::Infallible,
fmt::{Debug, Display},
marker::PhantomData,
};
use crate::Deserializer;
mod r#impl;
pub trait Error: core::error::Error + Sized {
fn custom<T>(msg: T) -> Self
where
T: Display;
fn unsupported_type(ty: impl Display) -> Self {
Self::custom(format_args!("unsupported type for serializer: {ty}"))
}
fn missing_field(field: impl Display) -> Self {
Self::custom(format_args!("missing field for serializer: {field}"))
}
}
pub trait Serialize {
fn serialize<S>(&self, serializer: S) -> Result<(), S::Error>
where
S: Serializer;
}
impl<T: ?Sized> Serialize for &T
where
T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<(), S::Error>
where
S: Serializer,
{
T::serialize(self, serializer)
}
}
pub trait Serializer {
type Error: Error;
const FLAT_CLASSES: bool;
#[inline]
fn layout_matches<'de, D>() -> bool
where
D: Deserializer<'de> + ?Sized,
{
D::FLAT_CLASSES == Self::FLAT_CLASSES
}
type SerializeClass<'a>: Serializer<Error = Self::Error>
where
Self: 'a;
type SerializeField<'a>: Serializer<Error = Self::Error>
where
Self: 'a;
type SerializeMethod<'a>: Serializer<Error = Self::Error>
where
Self: 'a;
type SerializeMethodArg<'a>: Serializer<Error = Self::Error>
where
Self: 'a;
type SerializeMethodVar<'a>: Serializer<Error = Self::Error>
where
Self: 'a;
fn serialize_comment(&mut self, value: &str) -> Result<(), Self::Error>;
fn serialize_class<Dst>(
&mut self,
src: &str,
dst: Dst,
) -> Result<Self::SerializeClass<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>;
fn serialize_field<Dst, DstDesc>(
&mut self,
src: &str,
desc: Option<&str>,
dst: Dst,
dst_desc: Option<DstDesc>,
) -> Result<Self::SerializeField<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
DstDesc: IntoIterator<Item: AsRef<str>>;
fn serialize_method<Dst, DstDesc>(
&mut self,
src: &str,
desc: Option<&str>,
dst: Dst,
dst_desc: Option<DstDesc>,
) -> Result<Self::SerializeMethod<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
DstDesc: IntoIterator<Item: AsRef<str>>;
fn serialize_method_arg<Dst>(
&mut self,
src: Option<&str>,
dst: Option<Dst>,
pos: Option<usize>,
lv_index: Option<usize>,
) -> Result<Self::SerializeMethodArg<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>;
fn serialize_method_var<Dst>(
&mut self,
src: Option<&str>,
dst: Option<Dst>,
lv_index: Option<usize>,
lvt_row_index: Option<usize>,
op_idx: Option<(usize, Option<usize>)>,
) -> Result<Self::SerializeMethodVar<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>;
}
impl<T> Serializer for &mut T
where
T: Serializer,
{
type Error = T::Error;
const FLAT_CLASSES: bool = T::FLAT_CLASSES;
#[inline]
fn layout_matches<'de, D>() -> bool
where
D: Deserializer<'de> + ?Sized,
{
T::layout_matches::<'de, D>()
}
type SerializeClass<'a>
= T::SerializeClass<'a>
where
Self: 'a;
type SerializeField<'a>
= T::SerializeField<'a>
where
Self: 'a;
type SerializeMethod<'a>
= T::SerializeMethod<'a>
where
Self: 'a;
type SerializeMethodArg<'a>
= T::SerializeMethodArg<'a>
where
Self: 'a;
type SerializeMethodVar<'a>
= T::SerializeMethodVar<'a>
where
Self: 'a;
#[inline]
fn serialize_comment(&mut self, value: &str) -> Result<(), Self::Error> {
T::serialize_comment(self, value)
}
#[inline]
fn serialize_class<Dst>(
&mut self,
src: &str,
dst: Dst,
) -> Result<Self::SerializeClass<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
{
T::serialize_class(self, src, dst)
}
#[inline]
fn serialize_field<Dst, DstDesc>(
&mut self,
src: &str,
desc: Option<&str>,
dst: Dst,
dst_desc: Option<DstDesc>,
) -> Result<Self::SerializeField<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
DstDesc: IntoIterator<Item: AsRef<str>>,
{
T::serialize_field(self, src, desc, dst, dst_desc)
}
#[inline]
fn serialize_method<Dst, DstDesc>(
&mut self,
src: &str,
desc: Option<&str>,
dst: Dst,
dst_desc: Option<DstDesc>,
) -> Result<Self::SerializeMethod<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
DstDesc: IntoIterator<Item: AsRef<str>>,
{
T::serialize_method(self, src, desc, dst, dst_desc)
}
#[inline]
fn serialize_method_arg<Dst>(
&mut self,
src: Option<&str>,
dst: Option<Dst>,
pos: Option<usize>,
lv_index: Option<usize>,
) -> Result<Self::SerializeMethodArg<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
{
T::serialize_method_arg(self, src, dst, pos, lv_index)
}
#[inline]
fn serialize_method_var<Dst>(
&mut self,
src: Option<&str>,
dst: Option<Dst>,
lv_index: Option<usize>,
lvt_row_index: Option<usize>,
op_idx: Option<(usize, Option<usize>)>,
) -> Result<Self::SerializeMethodVar<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
{
T::serialize_method_var(self, src, dst, lv_index, lvt_row_index, op_idx)
}
}
enum Unconstructable {}
#[allow(missing_debug_implementations)]
pub struct Impossible<Err>(Unconstructable, PhantomData<Err>);
impl<Err> Serializer for Impossible<Err>
where
Err: Error,
{
type Error = Err;
const FLAT_CLASSES: bool = false;
#[inline]
fn layout_matches<'de, D>() -> bool
where
D: Deserializer<'de> + ?Sized,
{
true
}
type SerializeClass<'a>
= Self
where
Self: 'a;
type SerializeField<'a>
= Self
where
Self: 'a;
type SerializeMethod<'a>
= Self
where
Self: 'a;
type SerializeMethodArg<'a>
= Self
where
Self: 'a;
type SerializeMethodVar<'a>
= Self
where
Self: 'a;
fn serialize_comment(&mut self, _value: &str) -> Result<(), Self::Error> {
Err(Err::unsupported_type("comment"))
}
fn serialize_class<Dst>(
&mut self,
_src: &str,
_dst: Dst,
) -> Result<Self::SerializeClass<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
{
Err(Err::unsupported_type("class"))
}
fn serialize_field<Dst, DstDesc>(
&mut self,
_src: &str,
_desc: Option<&str>,
_dst: Dst,
_dst_desc: Option<DstDesc>,
) -> Result<Self::SerializeField<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
DstDesc: IntoIterator<Item: AsRef<str>>,
{
Err(Err::unsupported_type("field"))
}
fn serialize_method<Dst, DstDesc>(
&mut self,
_src: &str,
_desc: Option<&str>,
_dst: Dst,
_dst_desc: Option<DstDesc>,
) -> Result<Self::SerializeMethod<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
DstDesc: IntoIterator<Item: AsRef<str>>,
{
Err(Err::unsupported_type("method"))
}
fn serialize_method_arg<Dst>(
&mut self,
_src: Option<&str>,
_dst: Option<Dst>,
_pos: Option<usize>,
_lv_index: Option<usize>,
) -> Result<Self::SerializeMethodArg<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
{
Err(Err::unsupported_type("method argument"))
}
fn serialize_method_var<Dst>(
&mut self,
_src: Option<&str>,
_dst: Option<Dst>,
_lv_index: Option<usize>,
_lvt_row_index: Option<usize>,
_op_idx: Option<(usize, Option<usize>)>,
) -> Result<Self::SerializeMethodVar<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
{
Err(Err::unsupported_type("method variable"))
}
}
pub struct Skip<Err>(PhantomData<Err>);
impl<Err> Skip<Err> {
#[inline]
pub const fn new() -> Self {
Self(PhantomData)
}
}
impl<Err> Default for Skip<Err> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<Err> Debug for Skip<Err> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("Skip").finish()
}
}
impl<Err> Serializer for Skip<Err>
where
Err: Error,
{
type Error = Err;
const FLAT_CLASSES: bool = false;
#[inline]
fn layout_matches<'de, D>() -> bool
where
D: Deserializer<'de> + ?Sized,
{
true
}
type SerializeClass<'a>
= Self
where
Self: 'a;
type SerializeField<'a>
= Self
where
Self: 'a;
type SerializeMethod<'a>
= Self
where
Self: 'a;
type SerializeMethodArg<'a>
= Self
where
Self: 'a;
type SerializeMethodVar<'a>
= Self
where
Self: 'a;
#[inline]
fn serialize_comment(&mut self, _value: &str) -> Result<(), Self::Error> {
Ok(())
}
#[inline]
fn serialize_class<Dst>(
&mut self,
_src: &str,
_dst: Dst,
) -> Result<Self::SerializeClass<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
{
Ok(Self::new())
}
#[inline]
fn serialize_field<Dst, DstDesc>(
&mut self,
_src: &str,
_desc: Option<&str>,
_dst: Dst,
_dst_desc: Option<DstDesc>,
) -> Result<Self::SerializeField<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
DstDesc: IntoIterator<Item: AsRef<str>>,
{
Ok(Self::new())
}
#[inline]
fn serialize_method<Dst, DstDesc>(
&mut self,
_src: &str,
_desc: Option<&str>,
_dst: Dst,
_dst_desc: Option<DstDesc>,
) -> Result<Self::SerializeMethod<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
DstDesc: IntoIterator<Item: AsRef<str>>,
{
Ok(Self::new())
}
#[inline]
fn serialize_method_arg<Dst>(
&mut self,
_src: Option<&str>,
_dst: Option<Dst>,
_pos: Option<usize>,
_lv_index: Option<usize>,
) -> Result<Self::SerializeMethodArg<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
{
Ok(Self::new())
}
#[inline]
fn serialize_method_var<Dst>(
&mut self,
_src: Option<&str>,
_dst: Option<Dst>,
_lv_index: Option<usize>,
_lvt_row_index: Option<usize>,
_op_idx: Option<(usize, Option<usize>)>,
) -> Result<Self::SerializeMethodVar<'_>, Self::Error>
where
Dst: IntoIterator<Item: AsRef<str>>,
{
Ok(Self::new())
}
}
impl Error for Infallible {
fn custom<T>(_msg: T) -> Self
where
T: Display,
{
unreachable!()
}
}