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};
172
173 #[test]
174 fn mapping_sends_preserves_creation_order_and_verdict() {
175 let actions: Actions<MailAddr, u8, Vec<u8>, Births<()>> = Actions::new(
176 vec![1, 2],
177 vec![
178 Create::new(3, (), CreationKind::Birth),
179 Create::new(4, (), CreationKind::replacement_of(3)),
180 ],
181 Step::Goto(7),
182 );
183
184 let mapped = actions.map_sends(|sends| sends.len());
185 assert_eq!(mapped.sends, 2);
186 assert_eq!(
187 mapped
188 .creates
189 .iter()
190 .map(|creation| creation.nonce)
191 .collect::<Vec<_>>(),
192 [3, 4]
193 );
194 assert!(matches!(mapped.become_, Step::Goto(7)));
195 }
196
197 #[test]
198 fn mapping_become_preserves_sends_and_creation_order() {
199 let actions: Actions<MailAddr, u8, Vec<u8>, Births<()>> = Actions::new(
200 vec![1, 2],
201 vec![Create::new(3, (), CreationKind::Birth)],
202 Step::Goto(7),
203 );
204
205 let mapped: Actions<MailAddr, Never, Vec<u8>, Births<()>> =
206 actions.map_become(|_| Step::Stop(Stopped));
207 assert_eq!(mapped.sends, [1, 2]);
208 assert_eq!(mapped.creates[0].nonce, 3);
209 assert!(matches!(mapped.become_, Step::Stop(Stopped)));
210 }
211}