crb_agent/performers/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
pub mod async_performer;
pub mod consume_performer;
pub mod duty_performer;
pub mod events_performer;
pub mod interrupt_performer;

#[cfg(feature = "sync")]
pub mod sync_performer;

use crate::address::Envelope;
use crate::agent::Agent;
use crate::context::Context;
use anyhow::Error;
use async_trait::async_trait;
use std::fmt;

pub trait AgentState: Send + 'static {}

impl<T> AgentState for T where T: Send + 'static {}

pub struct Next<T: ?Sized> {
    pub(crate) transition: Box<dyn StatePerformer<T>>,
}

impl<T> Next<T>
where
    T: Agent + ?Sized,
{
    pub fn new(performer: impl StatePerformer<T>) -> Self {
        Self {
            transition: Box::new(performer),
        }
    }
}

pub enum TransitionCommand<T> {
    Next(Next<T>),
    Stop(StopReason),
    ProcessEvents,
    InContext(Envelope<T>),
}

impl<T> fmt::Debug for TransitionCommand<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let value = match self {
            Self::Next(_) => "Next(_)",
            Self::Stop(reason) => &format!("Stop({reason:?})"),
            Self::ProcessEvents => "ProcessEvents",
            Self::InContext(_) => "InContext(_)",
        };
        write!(f, "TransitionCommand::{}", value)
    }
}

pub enum StopReason {
    Failed(Error),
    Interrupted,
    Done,
}

impl fmt::Debug for StopReason {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let value = match self {
            Self::Failed(_) => "Failed(_)",
            Self::Interrupted => "Interrupted",
            Self::Done => "Done",
        };
        write!(f, "StopReason::{}", value)
    }
}

pub enum ConsumptionReason {
    Transformed,
    Crashed(Error),
}

impl fmt::Debug for ConsumptionReason {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let value = match self {
            Self::Transformed => "Transformed",
            Self::Crashed(_) => "Crashed(_)",
        };
        write!(f, "ConsumptionReason::{}", value)
    }
}

pub enum Transition<T: Agent + ?Sized> {
    Continue {
        agent: T,
        command: TransitionCommand<T>,
    },
    Consume {
        reason: ConsumptionReason,
    },
}

impl<T: Agent> fmt::Debug for Transition<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Continue { command, .. } => {
                write!(f, "Transition::{command:?}")
            }
            Self::Consume { reason } => {
                write!(f, "Transition::{reason:?}")
            }
        }
    }
}

#[async_trait]
pub trait StatePerformer<T: Agent + ?Sized>: Send + 'static {
    async fn perform(&mut self, agent: T, session: &mut Context<T>) -> Transition<T>;
}