Skip to main content

behavior/transition/
sending.rs

1//! Typed send products and their accumulation contract.
2
3/// A product of independently typed send protocols.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct SendProduct<L, R> {
6    pub inner: L,
7    pub own: R,
8}
9
10/// The operation required to accumulate sends across transitions.
11pub trait SendAlgebra: Sized {
12    fn empty() -> Self;
13    fn append(&mut self, other: Self);
14}
15
16impl<T> SendAlgebra for Vec<T> {
17    fn empty() -> Self {
18        Vec::new()
19    }
20
21    fn append(&mut self, mut other: Self) {
22        Vec::append(self, &mut other);
23    }
24}
25
26impl<L: SendAlgebra, R: SendAlgebra> SendAlgebra for SendProduct<L, R> {
27    fn empty() -> Self {
28        Self {
29            inner: L::empty(),
30            own: R::empty(),
31        }
32    }
33
34    fn append(&mut self, other: Self) {
35        self.inner.append(other.inner);
36        self.own.append(other.own);
37    }
38}
39
40/// Requests interpreted by the runtime local to the emitting actor.
41///
42/// Unlike [`crate::Delivery`], a service request has no actor address. Its
43/// recipient is definitionally the interpreter of the actor whose transition
44/// emitted it. This distinct send lane lets interpreters route ordinary
45/// deliveries and local services with disjoint static implementations.
46#[derive(Debug, Clone, PartialEq, Eq)]
47pub struct ServiceSends<M> {
48    requests: Vec<M>,
49}
50
51impl<M> ServiceSends<M> {
52    #[must_use]
53    pub fn new(requests: Vec<M>) -> Self {
54        Self { requests }
55    }
56    #[must_use]
57    pub fn one(request: M) -> Self {
58        Self::new(vec![request])
59    }
60    #[must_use]
61    pub fn as_slice(&self) -> &[M] {
62        &self.requests
63    }
64    pub fn iter(&self) -> core::slice::Iter<'_, M> {
65        self.requests.iter()
66    }
67    #[must_use]
68    pub fn len(&self) -> usize {
69        self.requests.len()
70    }
71    #[must_use]
72    pub fn is_empty(&self) -> bool {
73        self.requests.is_empty()
74    }
75    pub fn extend(&mut self, requests: impl IntoIterator<Item = M>) {
76        self.requests.extend(requests);
77    }
78    #[must_use]
79    pub fn into_requests(self) -> Vec<M> {
80        self.requests
81    }
82}
83
84impl<M> core::ops::Index<usize> for ServiceSends<M> {
85    type Output = M;
86    fn index(&self, index: usize) -> &Self::Output {
87        &self.requests[index]
88    }
89}
90
91impl<M> IntoIterator for ServiceSends<M> {
92    type Item = M;
93    type IntoIter = std::vec::IntoIter<M>;
94    fn into_iter(self) -> Self::IntoIter {
95        self.requests.into_iter()
96    }
97}
98
99impl<'a, M> IntoIterator for &'a ServiceSends<M> {
100    type Item = &'a M;
101    type IntoIter = core::slice::Iter<'a, M>;
102    fn into_iter(self) -> Self::IntoIter {
103        self.requests.iter()
104    }
105}
106
107impl<M> SendAlgebra for ServiceSends<M> {
108    fn empty() -> Self {
109        Self::new(Vec::new())
110    }
111    fn append(&mut self, mut other: Self) {
112        self.requests.append(&mut other.requests);
113    }
114}