[−][src]Trait mode::Family
A meta-trait defining the common Base type and Mode storage conventions used by a related group of Mode
implementations. Modes can only transition to other Modes within the same Family, i.e. where both Modes
share the same Family associated type.
The Base type
The Base associated type may be either a dyn Trait or a concrete type that represents how the current Mode can
be accessed from outside the Automaton.
If given some dyn Trait, only functions common to the trait interface will be callable on the current
Mode, as the Automaton will only allow it to be borrowed via a trait reference. However, the Automaton
will allow swapping between different concrete implementations of this common interface, provided that the Mode
associated type is a pointer of some kind (e.g. Box) and they share the same Family associated type.
If given a concrete type, e.g. an enum or struct, all functions and members defined on the inner type will
be accessible from outside the Automaton. However, this also implies that all states in the Automaton will
be represented by instances of this same concrete type.
Usage
To define a new Family of Modes, simply define a new unit struct and impl Family for it. This will allow the
associated types within Family to be defined for that specific struct, with the struct representing the
common usage pattern of all Modes with a Family associated type equal to that struct. (See examples below.)
A Family where Base is a concrete type
use mode::{Family, Mode}; enum SomeMode { A, B, C } impl Mode for SomeMode { type Family = SomeFamily; } impl SomeMode { pub fn swap(self) -> Self { match self { Self::A => Self::B, Self::B => Self::C, Self::C => Self::A, } } } struct SomeFamily; impl Family for SomeFamily { type Base = SomeMode; // All SomeFamily Modes will be visible as SomeMode from outside the Automaton. type Mode = SomeMode; // The current Mode in the Automaton will be stored as a SomeMode in-place. }
A Family where Base is a dyn Trait
use mode::{Mode, Family}; trait SomeTrait : Mode<Family = SomeFamily> { // ... } struct SomeFamily; impl Family for SomeFamily { type Base = dyn SomeTrait; // All SomeFamily Modes will expose their SomeTrait interface via the Automaton. type Mode = Box<dyn SomeTrait>; // The current Mode in the Automaton will be stored as a Box<dyn SomeTrait>. }
Associated Types
type Base: ?Sized
The user-facing interface for the Mode that will be exposed via the Automaton::borrow_mode() and
Automaton::borrow_mode_mut() functions. This can be either a concrete type or a dyn Trait, depending on
whether Self::Mode is a pointer type or not.
NOTE: This is not the actual type that will be stored in Automaton. This is just the public interface
for the current Mode that will be exposed by the Automaton.
type Mode: Mode<Family = Self>
The actual type that will be stored in Automaton and moved into the Automaton::next() function. For a
Family where Self::Base is a concrete type, this should be set to the same type as Self::Base. On
the other hand, if Self::Base is a dyn Trait, this should usually be set to some pointer type capable of
storing Self::Base, e.g. Box<Self::Base> or Rc<Self::Base>.
Provided methods
fn automaton() -> Automaton<Self> where
Self::Mode: Default,
Self::Mode: Default,
Convenience function allowing an Automaton to be created for this Family type. Note that this is shorthand
for Automaton::new(), and therefore Self::Mode must implement Default. See
Automaton::new() for more details.
Usage
use mode::*; struct ModeWithDefault { count : u32 }; impl Mode for ModeWithDefault { type Family = SomeFamily; } impl Default for ModeWithDefault { fn default() -> Self { ModeWithDefault { count: 0 } } } // Create an Automaton with a default Mode. let mut automaton = SomeFamily::automaton();
fn automaton_with_mode(mode: Self::Mode) -> Automaton<Self>
Convenience function that returns a new Automaton for this Family type with the specified mode as current.
Note that this is shorthand for Automaton::with_mode(). See
Automaton::with_mode() for more details.
Usage
use mode::*; struct SomeFamily; impl Family for SomeFamily { type Base = SomeMode; type Mode = SomeMode; } enum SomeMode { A, B, C }; impl Mode for SomeMode { type Family = SomeFamily; } // Create an Automaton with A as the initial Mode. let mut automaton = SomeFamily::automaton_with_mode(SomeMode::A);