crb-agent 0.0.35

CRB | Composable Runtime Blocks | Agent
Documentation
use crate::agent::Agent;
use crate::context::Context;
use crate::performers::{Next, StatePerformer, StopReason, Transition, TransitionCommand};
use anyhow::Error;
use async_trait::async_trait;
use crb_runtime::ManagedContext;

impl<A> Next<A>
where
    A: Agent,
{
    pub fn done() -> Self {
        Self::new(StopPerformer {
            call_interrupt: false,
            reason: None,
        })
    }

    pub fn interrupt() -> Self {
        Self::new(StopPerformer {
            call_interrupt: true,
            reason: None,
        })
    }

    pub fn stop() -> Self {
        Self::stop_with_reason(StopReason::Stopped)
    }

    pub fn fail(err: Error) -> Self {
        Self::stop_with_reason(StopReason::Failed(err))
    }

    pub fn todo(reason: impl ToString) -> Self {
        let err = Error::msg(reason.to_string());
        Self::stop_with_reason(StopReason::Failed(err))
    }

    pub fn stop_with_reason(reason: StopReason) -> Self {
        Self::new(StopPerformer {
            call_interrupt: false,
            reason: Some(reason),
        })
    }
}

pub struct StopPerformer {
    call_interrupt: bool,
    reason: Option<StopReason>,
}

#[async_trait]
impl<A> StatePerformer<A> for StopPerformer
where
    A: Agent,
{
    async fn perform(&mut self, mut agent: A, ctx: &mut Context<A>) -> Transition<A> {
        if let Some(reason) = self.reason.take() {
            let command = TransitionCommand::Stop(reason);
            Transition::Continue { agent, command }
        } else {
            if self.call_interrupt {
                agent.interrupt(ctx);
            } else {
                ctx.shutdown();
            }
            let command = TransitionCommand::ProcessEvents;
            Transition::Continue { agent, command }
        }
    }
}