Struct Composite

Source
pub struct Composite<Data> {
    pub data: Data,
}
Expand description

The structure may be used to share data between states within the same Composite

Fields§

§data: Data

Implementations§

Source§

impl<Data> Composite<Data>

Implementing Composite methods

Source

pub fn new(data: Data) -> Self

Create a new Composite instance, sharing the data between all states within the Composite

Source

pub async fn init<'s, Factory, FactoryArg, Out, Err, Fut>( &'s mut self, f: Factory, arg: FactoryArg, ) -> Result<Out, Err>
where Factory: FnOnce(&'s mut Self, FactoryArg) -> Fut, Fut: Future<Output = Result<Transit<'s, Self, Out, Err>, Err>>, Out: Sized + Copy,

Composition of states, only one sub-state at a time. The function f is initializing the first sub state.

#Examples

    use async_std::prelude::*;
    use async_std::stream;
    use async_std::task;
    use async_hsm::{Composite, Transit, Builder, BuilderPair};
    use std::rc::Rc;
    use std::cell::RefCell;

    type Score = u32;
    type EnterStateScore = u32;
    type AppComposite = Composite<AppData>;
    type AppTransit<'s> = Transit<'s, AppComposite, Score, AppError>;
    type AppBuilder = Builder<AppComposite, EnterStateScore, Score, AppError>;
    type AppBuilderPair = BuilderPair<AppComposite, EnterStateScore, Score, AppError>;

    #[derive(Debug, Clone, PartialEq)]
    enum AppError { Failure }

    #[derive(Debug, Clone, PartialEq)]
    enum IoEvent { Ping, Pong, Terminate, Menu, Play }

    #[derive(Debug, Clone)]
    struct AppData { event: Rc<RefCell<stream::FromIter<std::vec::IntoIter<IoEvent>>>> }

    async fn ping<'s>(comp: &'s mut AppComposite, score: Score) -> Result<AppTransit<'s>, AppError> {
        let mut score = score + 1;
        let event = comp.data.event.clone();
        while let Some(event) = (*event).borrow_mut().next().await {
            match event {
                IoEvent::Pong => return Ok(Transit::To(Box::pin(pong(comp, score)))),
                _ => score += 1,
            }
        }
        Ok(Transit::Lift(score))
    }

    async fn pong<'s>(comp: &'s mut AppComposite, score: Score) -> Result<AppTransit<'s>, AppError> {
        let mut score = score + 1;
        let event = comp.data.event.clone();
        while let Some(event) = (*event).borrow_mut().next().await {
            match event {
                IoEvent::Ping => return Ok(Transit::To(Box::pin(ping(comp, score)))),
                _ => score += 1,
            }
        }
        Ok(Transit::Lift(score))
    }

    #[test]
    fn test_game() {
        let sequence = vec![ IoEvent::Ping, IoEvent::Pong, IoEvent::Ping, IoEvent::Pong];
        let event = Rc::new(RefCell::new(stream::from_iter(sequence)));
        let start_score = 0;
        let mut app = AppComposite::new(AppData { event: event });
        let result: Result<Score, AppError> = task::block_on(app.init(ping, start_score));
        assert_eq!(Ok(5), result);
    }

Auto Trait Implementations§

§

impl<Data> Freeze for Composite<Data>
where Data: Freeze,

§

impl<Data> RefUnwindSafe for Composite<Data>
where Data: RefUnwindSafe,

§

impl<Data> Send for Composite<Data>
where Data: Send,

§

impl<Data> Sync for Composite<Data>
where Data: Sync,

§

impl<Data> Unpin for Composite<Data>
where Data: Unpin,

§

impl<Data> UnwindSafe for Composite<Data>
where Data: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.