[][src]Macro validated_slice::impl_std_traits_for_owned_slice

macro_rules! impl_std_traits_for_owned_slice {
    (
        Std {
            core: $core:ident,
            alloc: $alloc:ident,
        };
        Spec {
            spec: $spec:ty,
            custom: $custom:ty,
            inner: $inner:ty,
            error: $error:ty,
            slice_custom: $slice_custom:ty,
            slice_inner: $slice_inner:ty,
            slice_error: $slice_error:ty,
        };
        $({$($rest:tt)*});* $(;)?
    ) => { ... };
    (
        Spec {
            spec: $spec:ty,
            custom: $custom:ty,
            inner: $inner:ty,
            error: $error:ty,
            slice_custom: $slice_custom:ty,
            slice_inner: $slice_inner:ty,
            slice_error: $slice_error:ty,
        };
        $({$($rest:tt)*});* $(;)?
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ Borrow<{SliceCustom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ Borrow<$param:ty> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ BorrowMut<{SliceCustom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ BorrowMut<$param:ty> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ ToOwned<Owned = {Custom}> for {SliceCustom} ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ AsMut<{SliceCustom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ AsMut<$param:ty> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ AsRef<{SliceCustom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ AsRef<$param:ty> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ From<&{SliceInner}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ From<&{SliceCustom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ From<{Inner}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ TryFrom<&{SliceInner}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ TryFrom<{Inner}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ Default ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ Debug ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ Display ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ Deref<Target = {SliceCustom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ DerefMut<Target = {SliceCustom}> ];
    ) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ FromStr ];
    ) => { ... };
    (@conv:as_slice, $spec:ty, $slice_spec:ty, $owned_ref:expr) => { ... };
    (@conv:as_mut_slice, $spec:ty, $slice_spec:ty, $owned_ref:expr) => { ... };
    (
        @impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty,
            $slice_spec:ty, $slice_custom:ty, $slice_inner:ty, $slice_error:ty);
        rest=[ $($rest:tt)* ];
    ) => { ... };
}

Implements std traits for the given custom slice type.

To implement PartialEq and PartialOrd, use impl_cmp_for_owned_slice! macro.

Usage

Examples

Assume you want to implement str and String types 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. */
}

/// My `String` type.
#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct AsciiString(Vec<u8>);

/// Spec for `MyString` type.
struct MyStringSpec;

impl validated_slice::OwnedSliceSpec for MyStringSpec {
    // My `String` type.
    type Custom = MyString;
    // Backend type of `MyString`.
    type Inner = Vec<u8>;
    // My `std::str::Utf8Error`.
    type Error = MyFromUtf8Error;
    // Spec of custom borrowed slice type, `MyStr` for this example.
    type SliceSpec = MyStrSpec;
    // Custom borrowed slice type.
    // This should be same as `MyStrSpec::Custom`.
    type SliceCustom = MyStr;
    // Backend type of the custom borrowed slice type.
    // This should be same as `MyStrSpec::Inner`.
    type SliceInner = [u8];
    // My `std::string::FromUtf8Error`.
    // This should be same as `MyStrSpec::Error`.
    type SliceError = MyFromUtf8Error;

    /* ... and methods. */
}

Then you can implement std traits as below:

This example is not tested
validated_slice::impl_std_traits_for_owned_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: MyStringSpec,
        custom: MyString,
        inner: Vec<u8>,
        error: MyFromUtf8Error,
        slice_custom: MyStr,
        slice_inner: [u8],
        slice_error: MyUtf8Error,
    };
    { AsRef<[u8]> };
    { AsRef<str> };
    { AsRef<{Custom}> };
    { ToOwned<Owned = {Custom}> for {SliceCustom} };
    { TryFrom<&{SliceInner}> };
    { TryFrom<{Inner}> };
    /* ... 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_owned_slice! {
    Std {
        core: core,
        alloc: alloc,
    };
    Spec { /* ... */ };
    /* ... */
}

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_owned_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::borrow
    • { Borrow<{SliceCustom}> };
    • { Borrow<any_ty> };
    • { BorrowMut<{SliceCustom}> };
    • { BorrowMut<any_ty> };
    • { ToOwned<Owned = {Custom}> for {SliceCustom} };
  • std::convert
    • { AsMut<{SliceCustom}> };
    • { AsMut<any_ty> };
    • { AsRef<{SliceCustom}> };
    • { AsRef<any_ty> };
    • { From<&{SliceInner}> };
    • { From<&{SliceCustom}> };
    • { From<{Inner}> };
    • { TryFrom<&{SliceInner}> };
    • { TryFrom<{Inner}> };
  • std::default
    • { Default };
  • std::fmt
    • { Debug };
    • { Display };
  • std::ops
    • { Deref<Target = {SliceCustom}> };
    • { DerefMut<Target = {SliceCustom}> };
  • std::str
    • { FromStr };