custom-slice

Build Status Minimum rustc version: 1.34

custom-slice-macros: Latest version Documentation

Proc-macros to define custom slice types easily (without users writing unsafe codes manually).

Usage

Consider the case you want to define slice types as below:

```rust /// Owned slice. // Sized type. pub struct Owned(OwnedInner);

/// Borrowed slice. // Unsized slice type. pub struct Slice(SliceInner);

impl std::borrow::Borrow for Owned { /* .. */ }

impl std::borrow::ToOwned for Slice { type Owned = Owned;

// ..

} ```

For example, if Owned is String and Slice is str, OwnedInner is Vec<u8> and SliceInner is [u8].

Basic

```rust customslicemacros::defineslicetypespair! { /// Owned slice. #[customslice(owned)] pub struct Owned(OwnedInner);

/// Borrowed slice.
#[repr(transparent)]
#[custom_slice(slice)]
pub struct Slice(SliceInner);

} ```

By this way, std::borrow::Borrow and std::borrow::ToOwned is automatically implemented.

Note that:

Constructor, error and validator

You can specify validator functions and error types for constructors.

This is useful for types which can have limited values (compared to the inner types). For example, Vec<u8> can have any binary data, but String can have valid UTF-8 sequences.

Example without validator:

``rust custom_slice_macros::define_slice_types_pair! { /// Owned slice. // Assumeownedinner: OwnedInner`. #[customslice(owned)] //let : Owned = Owned::new(ownedinner); #[customslice(newunchecked = "fn new")] pub struct Owned(OwnedInner);

/// Borrowed slice.
#[repr(transparent)]
// Assume `slice_inner_ref: &Slice` and `slice_inner_mut: &mut Slice`.
#[custom_slice(slice)]
//let _: &Slice = Slice::new(slice_inner_ref);
#[custom_slice(new = "fn new")]
//let _: &mut Slice = Slice::new_mut(slice_inner_mut);
#[custom_slice(new_mut = "fn new_mut")]
pub struct Slice(SliceInner);

} ```

Example with validator:

``rust custom_slice_macros::define_slice_types_pair! { /// Owned slice. // Assumeownedinner: OwnedInner`. #[customslice(owned)] //let : Owned = unsafe { Owned::newunchecked(ownedinner) }; #[customslice(newunchecked = "unsafe fn newunchecked")] //let : Result = Owned::new(ownedinner); #[customslice(newchecked = "pub fn new")] #[custom_slice(error( type = "ErrorWithInner", map = "{|e, v| Error { error: e, value: v } }" ))] pub struct Owned(OwnedInner);

/// Borrowed slice.
#[repr(transparent)]
// Assume `slice_inner_ref: &Slice` and `slice_inner_mut: &mut Slice`.
#[custom_slice(slice)]
//let _: &Slice = unsafe { Slice::new_unchecked(slice_inner_ref) };
#[custom_slice(new_unchecked = "unsafe fn new_unchecked")]
//let _: &mut Slice = unsafe { Slice::new_unchecked_mut(slice_inner_mut) };
#[custom_slice(new_unchecked_mut = "unsafe fn new_unchecked_mut")]
//let _: Result<&Slice, Error> = Slice::new(slice_inner_ref);
#[custom_slice(new_checked = "pub fn new")]
//let _: Result<&mut Slice, Error> = Slice::new_mut(slice_inner_mut);
#[custom_slice(new_checked_mut = "pub fn new_mut")]
#[custom_slice(error(type = "Error"))]
pub struct Slice(SliceInner);

/// Validates the given data.
///
/// Returns `Ok(())` for valid data, `Err(_)` for invalid data.
#[custom_slice(validator)]
fn validate(s: &SliceInner) -> Result<(), Error> {
    /* Do the validation. */
}

} ```

Accessors

You can define accessors to the inner types with meaningful name.

``rust custom_slice_macros::define_slice_types_pair! { /// Owned slice. // Assumeowned: Ownedandmut ownedmut: Owned`. #[customslice(owned)] //let : &OwnedInner = owned.get(); #[customslice(getref = "pub fn get")] //let _: &mut OwnedInner = ownedmut.getmut(); #[customslice(getmut = "fn getmut")] //let : OwnedInner = owned.intoinner(); #[customslice(intoinner = "pub fn into_inner")] pub struct Owned(OwnedInner);

/// Borrowed slice.
// Assume `slice_ref: &Slice` and `slice_mut: &mut Slice`.
#[repr(transparent)]
#[custom_slice(slice)]
//let _: &SliceInner = slice_ref.get();
#[custom_slice(get_ref = "pub fn get")]
//let _: &mut SliceInner = slice_mut.get_mut();
#[custom_slice(get_mut = "fn get_mut")]
pub struct Slice(SliceInner);

} ```

Deriving traits

custom_slice_macros::define_slice_types_pair! supports generating impls which should possibly require unsafe operations.

```rust customslicemacros::defineslicetypespair! { /// Owned slice. #[customslice(owned)] #[custom_slice(derive(BorrowMut, Deref, DerefMut))] pub struct Owned(OwnedInner);

/// Borrowed slice.
#[repr(transparent)]
#[custom_slice(slice)]
#[custom_slice(derive(DefaultRef, DefaultRefMut))]
pub struct Slice(SliceInner);

} ```

The following derive targets are available:

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.