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; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ From<&{Custom}> for &{Inner} ];
) => { ... };
(
@impl; ({$core:ident, $alloc:ident}, $spec:ty, $custom:ty, $inner:ty, $error:ty);
rest=[ From<&mut {Custom}> for &mut {Inner} ];
) => { ... };
(
@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)* ];
) => { ... };
}Expand description
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:
/// My `str` type.
#[repr(transparent)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MyStr([u8]);
/// Spec for `MyStr` type.
enum 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:
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:
// 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 &{Inner} };
- `{ From<&mut {Custom}> for &mut {Inner} };
- `{ 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}> };