Skip to main content

behavior/actor/
addressing.rs

1//! Typed actor addresses, routes, recipients, and deliveries.
2
3use core::marker::PhantomData;
4
5/// A pure actor-address namespace.
6pub trait Address: Copy + Eq {
7    type Nonce: Copy + Eq;
8
9    #[must_use]
10    fn birth(self, nonce: Self::Nonce) -> Self;
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub struct MailAddr(pub u64);
15
16impl Address for MailAddr {
17    type Nonce = u64;
18
19    fn birth(self, nonce: u64) -> Self {
20        Self(self.0 ^ nonce.wrapping_mul(0x9E37_79B9_7F4A_7C15))
21    }
22}
23
24/// An address expression for ordinary actor delivery.
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub enum Route<A: Address> {
27    Global(A),
28    Child(A::Nonce),
29}
30
31/// A recipient statically coupled to the message it accepts.
32pub struct Recipient<A: Address, M> {
33    route: Route<A>,
34    message: PhantomData<fn(M)>,
35}
36
37impl<A: Address, M> Copy for Recipient<A, M> {}
38
39impl<A: Address, M> Clone for Recipient<A, M> {
40    fn clone(&self) -> Self {
41        *self
42    }
43}
44
45impl<A: Address, M> Recipient<A, M> {
46    #[must_use]
47    pub fn global(address: A) -> Self {
48        Self::from_route(Route::Global(address))
49    }
50
51    #[must_use]
52    pub fn child(nonce: A::Nonce) -> Self {
53        Self::from_route(Route::Child(nonce))
54    }
55
56    #[must_use]
57    pub fn route(self) -> Route<A> {
58        self.route
59    }
60
61    const fn from_route(route: Route<A>) -> Self {
62        Self {
63            route,
64            message: PhantomData,
65        }
66    }
67}
68
69impl<A: Address, M> PartialEq for Recipient<A, M> {
70    fn eq(&self, other: &Self) -> bool {
71        self.route == other.route
72    }
73}
74
75impl<A: Address, M> Eq for Recipient<A, M> {}
76
77impl<A: Address + core::fmt::Debug, M> core::fmt::Debug for Recipient<A, M>
78where
79    A::Nonce: core::fmt::Debug,
80{
81    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
82        self.route.fmt(f)
83    }
84}
85
86/// One statically typed send operation.
87#[derive(Clone, PartialEq, Eq)]
88pub struct Delivery<A: Address, M> {
89    pub to: Recipient<A, M>,
90    pub message: M,
91}
92
93impl<A: Address, M> Delivery<A, M> {
94    #[must_use]
95    pub fn new(to: Recipient<A, M>, message: M) -> Self {
96        Self { to, message }
97    }
98}