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