Skip to main content

behavior/
user_event.rs

1//! The user-message lane and its composition contracts.
2
3use crate::actor::Address;
4
5/// The user-message event at the Agha floor.
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct User<A, M> {
8    pub from: A,
9    pub message: M,
10}
11
12/// A statically proven injection of one semantic input into a concrete event sum.
13///
14/// Implementations must select exactly one constructor and preserve `input`
15/// unchanged. Absence of an implementation means that the protocol does not
16/// accept that input.
17pub trait EventInput<Input>: Sized {
18    fn inject(input: Input) -> Self;
19}
20
21/// Attempt to route one input through a nested event product.
22///
23/// Unlike [`EventInput`], this is not an acceptance capability. It is the
24/// lossless routing operation used by an outer wrapper when it does not own an
25/// input itself. Rejection returns the original input unchanged.
26pub trait RouteInput<Input>: Sized {
27    /// # Errors
28    ///
29    /// Returns the original `input` unchanged when this event product does not
30    /// own or forward the corresponding semantic lane.
31    fn route(input: Input) -> Result<Self, Input>;
32}
33
34impl<A, M> EventInput<User<A, M>> for User<A, M> {
35    fn inject(input: User<A, M>) -> Self {
36        input
37    }
38}
39
40impl<A, M, Input> RouteInput<Input> for User<A, M> {
41    fn route(input: Input) -> Result<Self, Input> {
42        Err(input)
43    }
44}
45
46impl<A, M> User<A, M> {
47    #[must_use]
48    pub const fn new(from: A, message: M) -> Self {
49        Self { from, message }
50    }
51}
52
53impl<A, M> From<(A, M)> for User<A, M> {
54    fn from((from, message): (A, M)) -> Self {
55        Self::new(from, message)
56    }
57}
58
59/// Construction/extraction of the user lane through a composed event type.
60pub trait UserEvent: Sized {
61    type Addr: Address;
62    type Message;
63
64    fn user(from: Self::Addr, message: Self::Message) -> Self;
65
66    /// # Errors
67    /// Returns the unchanged event when it belongs to another composed lane.
68    fn into_user(self) -> Result<User<Self::Addr, Self::Message>, Self>;
69}
70
71impl<A: Address, M> UserEvent for User<A, M> {
72    type Addr = A;
73    type Message = M;
74
75    fn user(from: A, message: M) -> Self {
76        Self::new(from, message)
77    }
78    fn into_user(self) -> Result<Self, Self> {
79        Ok(self)
80    }
81}