[−][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 };