serde_describe 0.2.5

Make non-self-describing serde formats behave like they're self-describing.
Documentation
use serde::{Deserialize, Serialize};
use std::{borrow::Borrow, hash::Hash};

#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub(crate) struct TypeName(
    pub(crate) TypeNameIndex,
    pub(crate) Option<VariantNameIndex>,
);

macro_rules! u32_indices {
    ($($index_ty:ident => $error:ident,)+) => {
        $(
            #[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
            pub(crate) struct $index_ty(u32);

            impl From<$index_ty> for u32 {
                #[inline]
                fn from(index: $index_ty) -> u32 {
                    index.0.into()
                }
            }

            impl From<$index_ty> for usize {
                #[inline]
                fn from(index: $index_ty) -> usize {
                    usize::try_from(u32::from(index.0)).expect("usize must be at least 32-bits")
                }
            }

            impl TryFrom<usize> for $index_ty {
                type Error = $crate::builder::TraceLimitErrorKind;

                #[inline]
                fn try_from(value: usize) -> Result<Self, Self::Error> {
                    match u32::try_from(value) {
                        Ok(value) => Ok($index_ty(value)),
                        Err(_) => Err($crate::builder::TraceLimitErrorKind::$error),
                    }
                }
            }

            impl From<u32> for $index_ty {
                #[inline]
                fn from(value: u32) -> Self {
                    $index_ty(value)
                }
            }
        )+
    };
}
pub(crate) trait IsEmpty
where
    Self: 'static + Borrow<Self::Borrowed> + Sized,
{
    type Borrowed: ?Sized;
    const BORROWED_EMPTY: &Self::Borrowed;

    fn is_empty(&self) -> bool;
}

impl<ValueT> IsEmpty for Box<[ValueT]>
where
    ValueT: 'static,
{
    type Borrowed = [ValueT];
    const BORROWED_EMPTY: &Self::Borrowed = &[];

    #[inline]
    fn is_empty(&self) -> bool {
        (**self).is_empty()
    }
}

impl<ValueT> IsEmpty for Vec<ValueT>
where
    ValueT: 'static,
{
    type Borrowed = [ValueT];
    const BORROWED_EMPTY: &Self::Borrowed = &[];

    #[inline]
    fn is_empty(&self) -> bool {
        (**self).is_empty()
    }
}

impl IsEmpty for Box<str> {
    type Borrowed = str;
    const BORROWED_EMPTY: &<Self as IsEmpty>::Borrowed = "";

    #[inline]
    fn is_empty(&self) -> bool {
        (**self).is_empty()
    }
}

impl IsEmpty for &'static str {
    type Borrowed = str;
    const BORROWED_EMPTY: &<Self as IsEmpty>::Borrowed = "";

    #[inline]
    fn is_empty(&self) -> bool {
        (**self).is_empty()
    }
}

pub(crate) trait IndexIsEmpty:
    Sized + Copy + PartialEq + 'static + IsEmpty<Borrowed = Self>
{
    const EMPTY: Self;
}

impl<IndexT> IndexIsEmpty for IndexT
where
    IndexT: Copy + PartialEq + 'static + IsEmpty<Borrowed = Self>,
{
    const EMPTY: Self = *Self::BORROWED_EMPTY;
}

macro_rules! impl_is_empty {
    ($($index_ty:ident,)+) => {
        $(
            #[allow(unused)]
            impl IsEmpty for $index_ty {
                type Borrowed = Self;
                const BORROWED_EMPTY: &<Self as IsEmpty>::Borrowed = &Self(0);

                #[inline]
                fn is_empty(&self) -> bool {
                    *self == Self(0)
                }
            }
        )+
    };
}

u32_indices! {
    SchemaNodeIndex => SchemaNodes,
    SchemaNodeListIndex => SchemaNodeLists,
    MemberListIndex => MemberLists,
    MemberIndex => Members,
    TypeNameIndex => Names,
    VariantNameIndex => Names,
    FieldNameIndex => Names,
    FieldNameListIndex => FieldNameLists,
    TraceIndex => Values,
}

impl_is_empty! {
    SchemaNodeIndex,
    SchemaNodeListIndex,
    FieldNameListIndex,
    MemberListIndex,
}