1use super::sending::SendAlgebra;
4use crate::actor::{Address, BirthMode, Create};
5use crate::next::{Never, Step, Stopped};
6
7pub type Become<Ph = Never> = Step<Ph, Stopped>;
8
9pub struct Actions<A: Address, Ph, Sends, Birth: BirthMode> {
26 pub sends: Sends,
27 pub creates: Vec<Create<A, Birth::Child>>,
28 pub become_: Become<Ph>,
29}
30
31impl<A, Ph, Sends, Birth> core::fmt::Debug for Actions<A, Ph, Sends, Birth>
32where
33 A: Address + core::fmt::Debug,
34 A::Nonce: core::fmt::Debug,
35 Ph: core::fmt::Debug,
36 Sends: core::fmt::Debug,
37 Birth: BirthMode,
38 Birth::Child: core::fmt::Debug,
39{
40 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
41 formatter
42 .debug_struct("Actions")
43 .field("sends", &self.sends)
44 .field("creates", &self.creates)
45 .field("become", &self.become_)
46 .finish()
47 }
48}
49
50impl<A, Ph, Sends, Birth> PartialEq for Actions<A, Ph, Sends, Birth>
51where
52 A: Address + PartialEq,
53 A::Nonce: PartialEq,
54 Ph: PartialEq,
55 Sends: PartialEq,
56 Birth: BirthMode,
57 Birth::Child: PartialEq,
58{
59 fn eq(&self, other: &Self) -> bool {
60 self.sends == other.sends && self.creates == other.creates && self.become_ == other.become_
61 }
62}
63
64impl<A, Ph, Sends, Birth> Eq for Actions<A, Ph, Sends, Birth>
65where
66 A: Address + Eq,
67 A::Nonce: Eq,
68 Ph: Eq,
69 Sends: Eq,
70 Birth: BirthMode,
71 Birth::Child: Eq,
72{
73}
74
75impl<A: Address, Ph, Sends, Birth: BirthMode> Actions<A, Ph, Sends, Birth> {
76 #[must_use]
79 pub fn map_sends<Mapped>(
80 self,
81 map: impl FnOnce(Sends) -> Mapped,
82 ) -> Actions<A, Ph, Mapped, Birth> {
83 Actions {
84 sends: map(self.sends),
85 creates: self.creates,
86 become_: self.become_,
87 }
88 }
89
90 #[must_use]
93 pub fn map_become<NextPh>(
94 self,
95 map: impl FnOnce(Become<Ph>) -> Become<NextPh>,
96 ) -> Actions<A, NextPh, Sends, Birth> {
97 Actions {
98 sends: self.sends,
99 creates: self.creates,
100 become_: map(self.become_),
101 }
102 }
103}
104
105impl<A: Address, Ph, Sends: SendAlgebra, Birth: BirthMode> Actions<A, Ph, Sends, Birth> {
106 #[must_use]
107 pub const fn new(
108 sends: Sends,
109 creates: Vec<Create<A, Birth::Child>>,
110 become_: Become<Ph>,
111 ) -> Self {
112 Self {
113 sends,
114 creates,
115 become_,
116 }
117 }
118
119 #[must_use]
120 pub fn just(become_: Become<Ph>) -> Self {
121 Self {
122 sends: Sends::empty(),
123 creates: Vec::new(),
124 become_,
125 }
126 }
127
128 #[must_use]
129 pub fn cont() -> Self {
130 Self::just(Step::Continue)
131 }
132 #[must_use]
133 pub fn stop() -> Self {
134 Self::just(Step::Stop(Stopped))
135 }
136 #[must_use]
137 pub fn goto(phase: Ph) -> Self {
138 Self::just(Step::Goto(phase))
139 }
140
141 #[must_use]
143 pub fn send(sends: Sends) -> Self {
144 Self::new(sends, Vec::new(), Step::Continue)
145 }
146
147 #[must_use]
149 pub fn create(creates: Vec<Create<A, Birth::Child>>) -> Self {
150 Self::new(Sends::empty(), creates, Step::Continue)
151 }
152}
153
154impl<A: Address, Ph, Sends, Birth: BirthMode>
155 From<(Sends, Vec<Create<A, Birth::Child>>, Become<Ph>)> for Actions<A, Ph, Sends, Birth>
156{
157 fn from((sends, creates, become_): (Sends, Vec<Create<A, Birth::Child>>, Become<Ph>)) -> Self {
158 Self {
159 sends,
160 creates,
161 become_,
162 }
163 }
164}
165
166pub type Acted<A, Ph, Sends, Birth, E> = Result<Actions<A, Ph, Sends, Birth>, E>;
167
168#[cfg(test)]
169mod tests {
170 use super::*;
171 use crate::{Births, CreationKind, MailAddr, NoBirths};
172
173 #[test]
174 fn equality_and_debug_cover_every_named_effect_leg() {
175 type Plain = Actions<MailAddr, u8, Vec<u8>, NoBirths>;
176
177 let value = Plain::new(vec![1], Vec::new(), Step::Goto(3));
178 assert_eq!(value, Plain::new(vec![1], Vec::new(), Step::Goto(3)));
179 assert_ne!(value, Plain::new(vec![2], Vec::new(), Step::Goto(3)));
180 assert_ne!(value, Plain::new(vec![1], Vec::new(), Step::Goto(4)));
181 assert_ne!(value, Plain::new(vec![1], Vec::new(), Step::Continue));
182 assert_eq!(
183 format!("{value:?}"),
184 "Actions { sends: [1], creates: [], become: Goto(3) }"
185 );
186
187 type Creating = Actions<MailAddr, Never, Vec<u8>, Births<u8>>;
188 let created = Creating::new(
189 Vec::new(),
190 vec![Create::new(7, 9, CreationKind::Birth)],
191 Step::Continue,
192 );
193 let other_creation = Creating::new(
194 Vec::new(),
195 vec![Create::new(8, 9, CreationKind::Birth)],
196 Step::Continue,
197 );
198 assert_ne!(created, other_creation);
199 }
200
201 #[test]
202 fn mapping_sends_preserves_creation_order_and_verdict() {
203 let actions: Actions<MailAddr, u8, Vec<u8>, Births<()>> = Actions::new(
204 vec![1, 2],
205 vec![
206 Create::new(3, (), CreationKind::Birth),
207 Create::new(4, (), CreationKind::replacement_of(3)),
208 ],
209 Step::Goto(7),
210 );
211
212 let mapped = actions.map_sends(|sends| sends.len());
213 assert_eq!(mapped.sends, 2);
214 assert_eq!(
215 mapped
216 .creates
217 .iter()
218 .map(|creation| creation.nonce)
219 .collect::<Vec<_>>(),
220 [3, 4]
221 );
222 assert!(matches!(mapped.become_, Step::Goto(7)));
223 }
224
225 #[test]
226 fn mapping_become_preserves_sends_and_creation_order() {
227 let actions: Actions<MailAddr, u8, Vec<u8>, Births<()>> = Actions::new(
228 vec![1, 2],
229 vec![Create::new(3, (), CreationKind::Birth)],
230 Step::Goto(7),
231 );
232
233 let mapped: Actions<MailAddr, Never, Vec<u8>, Births<()>> =
234 actions.map_become(|_| Step::Stop(Stopped));
235 assert_eq!(mapped.sends, [1, 2]);
236 assert_eq!(mapped.creates[0].nonce, 3);
237 assert!(matches!(mapped.become_, Step::Stop(Stopped)));
238 }
239}