behavior/effects/
sending.rs1use core::marker::PhantomData;
4
5pub enum Own {}
7
8pub struct Inner<Path>(PhantomData<fn(Path)>);
10
11pub trait SendInput<Input, Path> {
17 fn emit(&mut self, input: Input);
18}
19
20#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct SendProduct<L, R> {
23 pub inner: L,
24 pub own: R,
25}
26
27impl<L, R> SendProduct<L, R> {
28 #[must_use]
29 pub const fn new(inner: L, own: R) -> Self {
30 Self { inner, own }
31 }
32
33 #[must_use]
34 pub fn split(self) -> (L, R) {
35 (self.inner, self.own)
36 }
37}
38
39impl<L, R> From<(L, R)> for SendProduct<L, R> {
40 fn from((inner, own): (L, R)) -> Self {
41 Self::new(inner, own)
42 }
43}
44
45pub trait SendAlgebra: Sized {
47 fn empty() -> Self;
48 fn append(&mut self, other: Self);
49
50 #[must_use]
51 fn combine(mut self, other: Self) -> Self {
52 self.append(other);
53 self
54 }
55
56 fn send<Input, Path>(&mut self, input: Input)
58 where
59 Self: SendInput<Input, Path>,
60 {
61 <Self as SendInput<Input, Path>>::emit(self, input);
62 }
63
64 #[must_use]
66 fn sending<Input, Path>(input: Input) -> Self
67 where
68 Self: SendInput<Input, Path>,
69 {
70 let mut sends = Self::empty();
71 sends.send(input);
72 sends
73 }
74}
75
76impl<T> SendAlgebra for Vec<T> {
77 fn empty() -> Self {
78 Vec::new()
79 }
80
81 fn append(&mut self, mut other: Self) {
82 Vec::append(self, &mut other);
83 }
84}
85
86impl<T> SendInput<T, Own> for Vec<T> {
87 fn emit(&mut self, input: T) {
88 self.push(input);
89 }
90}
91
92impl<L: SendAlgebra, R: SendAlgebra> SendAlgebra for SendProduct<L, R> {
93 fn empty() -> Self {
94 Self::new(L::empty(), R::empty())
95 }
96
97 fn append(&mut self, other: Self) {
98 let (inner, own) = other.split();
99 self.inner.append(inner);
100 self.own.append(own);
101 }
102}
103
104#[derive(Debug, Clone, PartialEq, Eq)]
111pub struct ServiceSends<M> {
112 requests: Vec<M>,
113}
114
115impl<M> ServiceSends<M> {
116 #[must_use]
117 pub fn new(requests: Vec<M>) -> Self {
118 Self { requests }
119 }
120 #[must_use]
121 pub fn one(request: M) -> Self {
122 Self::new(vec![request])
123 }
124 #[must_use]
125 pub fn as_slice(&self) -> &[M] {
126 &self.requests
127 }
128 pub fn iter(&self) -> core::slice::Iter<'_, M> {
129 self.requests.iter()
130 }
131 #[must_use]
132 pub fn len(&self) -> usize {
133 self.requests.len()
134 }
135 #[must_use]
136 pub fn is_empty(&self) -> bool {
137 self.requests.is_empty()
138 }
139 pub fn extend(&mut self, requests: impl IntoIterator<Item = M>) {
140 self.requests.extend(requests);
141 }
142 #[must_use]
143 pub fn into_requests(self) -> Vec<M> {
144 self.requests
145 }
146}
147
148impl<M> core::ops::Index<usize> for ServiceSends<M> {
149 type Output = M;
150 fn index(&self, index: usize) -> &Self::Output {
151 &self.requests[index]
152 }
153}
154
155impl<M> IntoIterator for ServiceSends<M> {
156 type Item = M;
157 type IntoIter = std::vec::IntoIter<M>;
158 fn into_iter(self) -> Self::IntoIter {
159 self.requests.into_iter()
160 }
161}
162
163impl<'a, M> IntoIterator for &'a ServiceSends<M> {
164 type Item = &'a M;
165 type IntoIter = core::slice::Iter<'a, M>;
166 fn into_iter(self) -> Self::IntoIter {
167 self.requests.iter()
168 }
169}
170
171impl<M> SendAlgebra for ServiceSends<M> {
172 fn empty() -> Self {
173 Self::new(Vec::new())
174 }
175 fn append(&mut self, mut other: Self) {
176 self.requests.append(&mut other.requests);
177 }
178}
179
180impl<M> SendInput<M, Own> for ServiceSends<M> {
181 fn emit(&mut self, input: M) {
182 self.requests.push(input);
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189
190 #[test]
191 fn send_algebra_obeys_identity_and_associativity() {
192 let values = vec![1, 2];
193 assert_eq!(Vec::new().combine(values.clone()), values);
194 assert_eq!(values.clone().combine(Vec::new()), values);
195
196 let left = vec![1].combine(vec![2]).combine(vec![3]);
197 let right = vec![1].combine(vec![2].combine(vec![3]));
198 assert_eq!(left, right);
199 }
200}