Skip to main content

behavior/calculus/
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    fn route(input: Input) -> Result<Self, Input>;
28}
29
30impl<A, M> EventInput<User<A, M>> for User<A, M> {
31    fn inject(input: User<A, M>) -> Self {
32        input
33    }
34}
35
36impl<A, M, Input> RouteInput<Input> for User<A, M> {
37    fn route(input: Input) -> Result<Self, Input> {
38        Err(input)
39    }
40}
41
42impl<A, M> User<A, M> {
43    #[must_use]
44    pub const fn new(from: A, message: M) -> Self {
45        Self { from, message }
46    }
47}
48
49impl<A, M> From<(A, M)> for User<A, M> {
50    fn from((from, message): (A, M)) -> Self {
51        Self::new(from, message)
52    }
53}
54
55/// Construction/extraction of the user lane through a composed event type.
56pub trait UserEvent: Sized {
57    type Addr: Address;
58    type Message;
59
60    fn user(from: Self::Addr, message: Self::Message) -> Self;
61
62    /// # Errors
63    /// Returns the unchanged event when it belongs to another composed lane.
64    fn into_user(self) -> Result<User<Self::Addr, Self::Message>, Self>;
65}
66
67impl<A: Address, M> UserEvent for User<A, M> {
68    type Addr = A;
69    type Message = M;
70
71    fn user(from: A, message: M) -> Self {
72        Self::new(from, message)
73    }
74    fn into_user(self) -> Result<Self, Self> {
75        Ok(self)
76    }
77}