[−][src]Macro validated_slice::impl_std_traits_for_owned_slice
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:
/// 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:
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:
// 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 };