[][src]Macro validated_slice::impl_std_traits_for_slice

macro_rules! impl_std_traits_for_slice {
    (
        Spec {
            spec: $spec:ty,
            custom: $custom:ty,
            inner: $inner:ty,
            error: $error:ty,
        };
        $({$($rest:tt)*});* $(;)?
    ) => { ... };
    (
        Std {
            core: $core:ident,
            alloc: $alloc:ident,
        };
        Spec {
            spec: $spec:ty,
            custom: $custom:ty,
            inner: $inner:ty,
            error: $error:ty,
        };
        $({$($rest:tt)*});* $(;)?
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ AsMut<{Custom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ AsMut<$param:ty> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ AsRef<{Custom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ AsRef<{Custom}> for Cow<{Custom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ AsRef<$param:ty> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ AsRef<$param:ty> for Cow<{Custom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ From<&{Inner}> for &{Custom} ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ From<&mut {Inner}> for &mut {Custom} ];
    ) => { ... };
    (
        @impl [smartptr]; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ From<&{Custom}> for $($smartptr:ident)::* <{Custom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ From<&{Custom}> for Arc<{Custom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ From<&{Custom}> for Box<{Custom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ From<&{Custom}> for Rc<{Custom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ TryFrom<&{Inner}> for &{Custom} ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ TryFrom<&mut {Inner}> for &mut {Custom} ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ Default for &{Custom} ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ Default for &mut {Custom} ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ Debug ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ Display ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ Deref<Target = {Inner}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ DerefMut<Target = {Inner}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
        rest=[ $($rest:tt)* ];
    ) => { ... };
}

Implements std traits for the given custom slice type.

To implement PartialEq and PartialOrd, use impl_cmp_for_slice! macro.

Usage

Examples

Assume you want to implement str type manually by yourself. Then you will have the type definitions below:

This example is not tested
/// My `str` type.
#[repr(transparent)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MyStr([u8]);

/// Spec for `MyStr` type.
struct MyStrSpec;

impl validated_slice::SliceSpec for MyStrSpec {
    // My `str` type.
    type Custom = MyStr;
    // Backend type of `MyStr`.
    type Inner = [u8];
    // My `std::str::Utf8Error`.
    type Error = MyUtf8Error;

    /* ... and methods. */
}

Then you can implement std traits as below:

This example is not tested
validated_slice::impl_std_traits_for_slice! {
    // `Std` is omissible.
    Std {
        // Module identifier of `core` crate.
        // Default is `std`.
        core: core,
        // Module identifier of `alloc` crate.
        // Default is `std`.
        alloc: alloc,
    };
    Spec {
        spec: MyStrSpec,
        custom: MyStr,
        inner: [u8],
        error: MyUtf8Error,
    };
    { AsRef<[u8]> };
    { AsRef<str> };
    { AsRef<{Custom}> };
    { From<&{Custom}> for Arc<{Custom}> };
    /* ... and more traits you want! */
}

Core and alloc

For no_std use, the macro uses custom core and alloc crate if given. You can support both nostd and non-nostd environment as below:

This example is not tested
// Use `std` when available.
#[cfg(feature = "std")]
use alloc as std;
// Use external `alloc` crate when nostd.
#[cfg(not(feature = "std"))]
use alloc;

validated_slice::impl_std_traits_for_slice! {
    Std {
        core: core,
        alloc: alloc,
    };
    Spec { /* ... */ };
    /* ... */
}

When you don't need alloc crate on nostd build, value of alloc field is not used. Simply specify alloc: alloc, or something.

Type names

As type name, you can use {Custom} and {Inner} instead of a real type name. They are replaced to the specified custom and inner types.

Arc<ty>, Box<ty>, Cow<ty>, and Rc<ty> will be also replaced to std::sync::Arc<ty>, std::boxed::Box<ty>, std::borrow::Cow<'_, ty>, and std::rc::Rc<ty>, respectively. They are checked symbolically, so they cannot be specified by type aliases, or path names such as std::sync::Arc<ty>.

Supported trait impls

NOTE: To implemente PartialEq and PartialOrd, use impl_cmp_for_slice! macro.

Each trait impl is specified by { TraitName<TyParams> for TyImplTarget }; format. <TyParams> part and for TyImplTarget part is optional.

Default impl target is {Custom}, and it should NOT be specified explicitly. Explicit for {Custom} is not supported and will cause compile error.

Supported trait impls are:

  • std::convert
    • { AsMut<{Custom}> };
    • { AsMut<any_ty> };
    • { AsRef<{Custom}> };
    • { AsRef<{Custom}> for Cow<{Custom}> };
    • { AsRef<any_ty> };
    • { AsRef<any_ty> for Cow<{Custom}> };
    • `{ From<&{Inner}> for &{Custom} };
    • `{ From<&mut {Inner}> for &mut {Custom} };
    • `{ From<&{Custom}> for Arc<{Custom}> };
    • `{ From<&{Custom}> for Box<{Custom}> };
    • `{ From<&{Custom}> for Rc<{Custom}> };
    • `{ TryFrom<&{Inner}> for &{Custom} };
    • `{ TryFrom<&mut {Inner}> for &mut {Custom} };
  • std::default
    • { Default for &{Custom} };
    • { Default for &mut {Custom} };
  • std::fmt
    • { Debug };
    • { Display };
  • std::ops
    • { Deref<Target = {Inner}> };
    • { DerefMut<Target = {Inner}> };