[][src]Macro typestate::typestate

macro_rules! typestate {
    ($vis:vis $struct_name:ident <$state_name:ident> [$($typestate:ident),+] {$($field:ident:$field_ty:ty),*}) => { ... };
    (limited
        $vis:vis
        $struct_name:ident
        <$state_name:ident:$state_trait:ident>
        [$($typestate:ident),+]
        {$($field:ident:$field_ty:ty),*}
    ) => { ... };
    (limited
        $vis:vis
        $struct_name:ident
        <$state_name:ident>
        [$($typestate:ident),+]
        {$($field:ident:$field_ty:ty),*}
    ) => { ... };
    (limited
        $vis:vis
        $struct_name:ident
        [$($typestate:ident),+]
        {$($field:ident:$field_ty:ty),*}
    ) => { ... };
    (strict
        $vis:vis
        $struct_name:ident
        <$state_name:ident:$state_trait:ident>
        ($sealed_mod:ident::$sealed_trait:ident)
        [$($typestate:ident),+]
        {$($field:ident:$field_ty:ty),*}
    ) => { ... };
    (strict
        $vis:vis
        $struct_name:ident
        <$state_name:ident:$state_trait:ident>
        ($sealed_trait:ident)
        [$($typestate:ident),+]
        {$($field:ident:$field_ty:ty),*}
    ) => { ... };
    (strict
        $vis:vis
        $struct_name:ident
        <$state_name:ident:$state_trait:ident>
        [$($typestate:ident),+]
        {$($field:ident:$field_ty:ty),*}
    ) => { ... };
    (strict
        $vis:vis
        $struct_name:ident
        <$state_name:ident>
        [$($typestate:ident),+]
        {$($field:ident:$field_ty:ty),*}
    ) => { ... };
    (strict
        $vis:vis
        $struct_name:ident
        [$($typestate:ident),+]
        {$($field:ident:$field_ty:ty),*}
    ) => { ... };
}

Describe a new struct and its possible typestates.

Typestate descriptions can be prepended with the limited or strict keywords, without them the resulting expansion can be extended by a user without bounds.

The limited keyword limits the possible state types with a trait bound, the resulting expasion will look similar to:

trait Limit {}
struct S<State> where S: Limit { /**/ }

The limited keyword generates the new trait to avoid users from writing an implementation for any type. To add a new state to the State set, the new struct must implement the trait bound.

struct NewState;
impl Limit for NewState {}
impl S<NewState> {} // now valid

The strict keyword implements the sealed trait pattern. Making external users are unable to extend the State set.

Syntax:

(limited|strict)? $visibility? $struct_name
$(<$state_name $(:$state_trait_bound)?>)?
($($strict_mod_name::)? $strict_mod_trait?)?
[$($typestate),+]
{$($struct_field),+}

Example of unconstrained typestate:

typestate!(
    Drone [Idle, Hovering, Flying] {
        x: f32,
        y: f32
    }
);

Example of a limited typestate:

typestate!(
    limited Drone [Idle, Hovering, Flying] {
        x: f32,
        y: f32
    }
);

Example of a strict typestate:

typestate!(
    strict Drone [Idle, Hovering, Flying] {
        x: f32,
        y: f32
    }
);