macro_rules! impl_cmp {
    ($ty_common:ty, $ty_lhs:ty, $ty_rhs:ty) => {
        impl PartialEq<$ty_rhs> for $ty_lhs {
            fn eq(&self, o: &$ty_rhs) -> bool {
                <$ty_common as PartialEq<$ty_common>>::eq(self.as_ref(), o.as_ref())
            }
        }
        impl PartialEq<$ty_lhs> for $ty_rhs {
            fn eq(&self, o: &$ty_lhs) -> bool {
                <$ty_common as PartialEq<$ty_common>>::eq(self.as_ref(), o.as_ref())
            }
        }
        impl PartialOrd<$ty_rhs> for $ty_lhs {
            fn partial_cmp(&self, o: &$ty_rhs) -> Option<std::cmp::Ordering> {
                <$ty_common as PartialOrd<$ty_common>>::partial_cmp(self.as_ref(), o.as_ref())
            }
        }
        impl PartialOrd<$ty_lhs> for $ty_rhs {
            fn partial_cmp(&self, o: &$ty_lhs) -> Option<std::cmp::Ordering> {
                <$ty_common as PartialOrd<$ty_common>>::partial_cmp(self.as_ref(), o.as_ref())
            }
        }
    };
}
macro_rules! impl_conv_and_cmp {
    (
        source: {
            owned: $owned:ty,
            slice: $slice:ty,
            creation_error: $ty_creation_error:ident,
            validation_error: $ty_validation_error:ident,
        },
        target: [
        $(
            {
                owned: $target_owned:ty,
                slice: $target_slice:ty,
            }
        ),+ $(,)?
        ],
    ) => {
        $(
            impl From<$owned> for $target_owned {
                fn from(s: $owned) -> $target_owned {
                    unsafe {
                        
                        
                        <$target_owned>::new_unchecked(s.into())
                    }
                }
            }
            impl<'a> From<&'a $slice> for &'a $target_slice {
                fn from(s: &'a $slice) -> &'a $target_slice {
                    s.as_ref()
                }
            }
            impl std::convert::TryFrom<$target_owned> for $owned {
                type Error = $ty_creation_error<String>;
                fn try_from(v: $target_owned) -> Result<Self, Self::Error> {
                    Self::try_from(Into::<String>::into(v))
                }
            }
            impl<'a> std::convert::TryFrom<&'a $target_slice> for &'a $slice {
                type Error = $ty_validation_error;
                fn try_from(v: &'a $target_slice) -> Result<Self, Self::Error> {
                    Self::try_from(AsRef::<str>::as_ref(v))
                }
            }
            impl AsRef<$target_slice> for $owned {
                fn as_ref(&self) -> &$target_slice {
                    AsRef::<$slice>::as_ref(self).as_ref()
                }
            }
            impl AsRef<$target_slice> for $slice {
                fn as_ref(&self) -> &$target_slice {
                    unsafe {
                        
                        
                        <$target_slice>::new_unchecked(self.as_ref())
                    }
                }
            }
            impl_cmp!($target_slice, $owned, $target_slice);
            impl_cmp!($target_slice, $owned, &$target_slice);
            impl_cmp!($target_slice, $owned, std::borrow::Cow<'_, $target_slice>);
            impl_cmp!($target_slice, $slice, $target_slice);
            impl_cmp!($target_slice, $slice, &$target_slice);
            impl_cmp!($target_slice, $slice, $target_owned);
            impl_cmp!($target_slice, $slice, std::borrow::Cow<'_, $target_slice>);
            impl_cmp!($target_slice, &$slice, $target_slice);
            impl_cmp!($target_slice, &$slice, $target_owned);
            impl_cmp!($target_slice, &$slice, std::borrow::Cow<'_, $target_slice>);
        )*
    };
}
macro_rules! impl_basics {
    (
        Slice {
            spec: $slice_spec:ident,
            custom: $slice:ident,
            validator: $validator:expr,
            error: $slice_error:ty,
        },
        Owned {
            spec: $owned_spec:ident,
            custom: $owned:ident,
            error: $owned_error:ty,
        },
    ) => {
        
        enum $slice_spec {}
        impl validated_slice::SliceSpec for $slice_spec {
            type Custom = $slice;
            type Inner = str;
            type Error = $slice_error;
            #[inline]
            fn validate(s: &Self::Inner) -> Result<(), Self::Error> {
                $validator(s)
            }
            validated_slice::impl_slice_spec_methods! {
                field=0;
                methods=[
                    as_inner,
                    as_inner_mut,
                    from_inner_unchecked,
                    from_inner_unchecked_mut,
                ];
            }
        }
        validated_slice::impl_std_traits_for_slice! {
            Spec {
                spec: $slice_spec,
                custom: $slice,
                inner: str,
                error: $slice_error,
            };
            { AsRef<str> };
            { AsRef<{Custom}> };
            { From<&{Custom}> for Arc<{Custom}> };
            { From<&{Custom}> for Box<{Custom}> };
            { From<&{Custom}> for Rc<{Custom}> };
            { TryFrom<&{Inner}> for &{Custom} };
            { Default for &{Custom} };
            { Display };
        }
        validated_slice::impl_cmp_for_slice! {
            Spec {
                spec: $slice_spec,
                custom: $slice,
                inner: str,
                base: Inner,
            };
            Cmp { PartialEq, PartialOrd };
            { ({Custom}), (&{Custom}), rev };
            { ({Custom}), (Cow<{Custom}>), rev };
            { ({Custom}), ({Inner}), rev };
            { ({Custom}), (&{Inner}), rev };
            { (&{Custom}), ({Inner}), rev };
            { ({Custom}), (Cow<{Inner}>), rev };
            { (&{Custom}), (Cow<{Inner}>), rev };
        }
        
        enum $owned_spec {}
        impl validated_slice::OwnedSliceSpec for $owned_spec {
            type Custom = $owned;
            type Inner = String;
            type Error = $owned_error;
            type SliceSpec = $slice_spec;
            type SliceCustom = $slice;
            type SliceInner = str;
            type SliceError = $slice_error;
            #[inline]
            fn convert_validation_error(e: Self::SliceError, v: Self::Inner) -> Self::Error {
                <$owned_error>::new(e, v)
            }
            #[inline]
            fn as_slice_inner(s: &Self::Custom) -> &Self::SliceInner {
                &s.0
            }
            #[inline]
            fn as_slice_inner_mut(s: &mut Self::Custom) -> &mut Self::SliceInner {
                &mut s.0
            }
            #[inline]
            fn inner_as_slice_inner(s: &Self::Inner) -> &Self::SliceInner {
                s
            }
            #[inline]
            unsafe fn from_inner_unchecked(s: Self::Inner) -> Self::Custom {
                $owned(s)
            }
            #[inline]
            fn into_inner(s: Self::Custom) -> Self::Inner {
                s.0
            }
        }
        validated_slice::impl_std_traits_for_owned_slice! {
            Spec {
                spec: $owned_spec,
                custom: $owned,
                inner: String,
                error: $owned_error,
                slice_custom: $slice,
                slice_inner: str,
                slice_error: $slice_error,
            };
            { Borrow<str> };
            { Borrow<{SliceCustom}> };
            { ToOwned<Owned = {Custom}> for {SliceCustom} };
            { AsRef<str> };
            { AsRef<{SliceCustom}> };
            { From<{Custom}> for {Inner} };
            { TryFrom<{Inner}> };
            { Display };
            { Deref<Target = {SliceCustom}> };
            { FromStr };
        }
        validated_slice::impl_cmp_for_owned_slice! {
            Spec {
                spec: $owned_spec,
                custom: $owned,
                inner: String,
                slice_custom: $slice,
                slice_inner: str,
                base: Inner,
            };
            Cmp { PartialEq, PartialOrd };
            { ({Custom}), ({SliceCustom}), rev };
            { ({Custom}), (&{SliceCustom}), rev };
            { ({Custom}), (Cow<{SliceCustom}>), rev };
            { ({Custom}), ({SliceInner}), rev };
            { ({Custom}), (&{SliceInner}), rev };
            { ({Custom}), (Cow<{SliceInner}>), rev };
        }
    };
}
macro_rules! impl_serde {
    (
        expecting: $expecting:expr,
        slice: $slice:ident,
        owned: $owned:ident,
    ) => {
        #[cfg(feature = "serde")]
        mod __serde {
            use super::{$owned, $slice};
            use std::{convert::TryFrom, fmt};
            use serde::{
                de::{self, Visitor},
                Deserialize, Deserializer,
            };
            
            #[derive(Debug, Clone, Copy)]
            struct CustomStringVisitor;
            impl<'de> Visitor<'de> for CustomStringVisitor {
                type Value = $owned;
                fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    f.write_str($expecting)
                }
                fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
                where
                    E: de::Error,
                {
                    <&$slice>::try_from(v)
                        .map(ToOwned::to_owned)
                        .map_err(E::custom)
                }
                fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
                where
                    E: de::Error,
                {
                    <$owned>::try_from(v).map_err(E::custom)
                }
            }
            impl<'de> Deserialize<'de> for $owned {
                fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
                where
                    D: Deserializer<'de>,
                {
                    deserializer.deserialize_str(CustomStringVisitor)
                }
            }
            
            #[derive(Debug, Clone, Copy)]
            struct CustomStrVisitor;
            impl<'de> Visitor<'de> for CustomStrVisitor {
                type Value = &'de $slice;
                fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    f.write_str($expecting)
                }
                fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
                where
                    E: de::Error,
                {
                    <&'de $slice>::try_from(v).map_err(E::custom)
                }
            }
            impl<'de: 'a, 'a> Deserialize<'de> for &'a $slice {
                fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
                where
                    D: Deserializer<'de>,
                {
                    deserializer.deserialize_string(CustomStrVisitor)
                }
            }
        }
    };
}