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: Address, Ph, Sends, Birth: BirthMode> Actions<A, Ph, Sends, Birth> {
33 #[must_use]
36 pub fn map_sends<Mapped>(
37 self,
38 map: impl FnOnce(Sends) -> Mapped,
39 ) -> Actions<A, Ph, Mapped, Birth> {
40 Actions {
41 sends: map(self.sends),
42 creates: self.creates,
43 become_: self.become_,
44 }
45 }
46
47 #[must_use]
50 pub fn map_become<NextPh>(
51 self,
52 map: impl FnOnce(Become<A, Ph>) -> Become<A, NextPh>,
53 ) -> Actions<A, NextPh, Sends, Birth> {
54 Actions {
55 sends: self.sends,
56 creates: self.creates,
57 become_: map(self.become_),
58 }
59 }
60}
61
62impl<A: Address, Ph, Sends: SendAlgebra, Birth: BirthMode> Actions<A, Ph, Sends, Birth> {
63 #[must_use]
64 pub const fn new(
65 sends: Sends,
66 creates: Vec<Create<A, Birth::Child>>,
67 become_: Become<A, Ph>,
68 ) -> Self {
69 Self {
70 sends,
71 creates,
72 become_,
73 }
74 }
75
76 #[must_use]
77 pub fn just(become_: Become<A, Ph>) -> Self {
78 Self {
79 sends: Sends::empty(),
80 creates: Vec::new(),
81 become_,
82 }
83 }
84
85 #[must_use]
86 pub fn cont() -> Self {
87 Self::just(Step::Continue)
88 }
89 #[must_use]
90 pub fn stop(exit: Exit<A>) -> Self {
91 Self::just(Step::Stop(exit))
92 }
93 #[must_use]
94 pub fn goto(phase: Ph) -> Self {
95 Self::just(Step::Goto(phase))
96 }
97}
98
99impl<A: Address, Ph, Sends, Birth: BirthMode>
100 From<(Sends, Vec<Create<A, Birth::Child>>, Become<A, Ph>)> for Actions<A, Ph, Sends, Birth>
101{
102 fn from(
103 (sends, creates, become_): (Sends, Vec<Create<A, Birth::Child>>, Become<A, Ph>),
104 ) -> Self {
105 Self {
106 sends,
107 creates,
108 become_,
109 }
110 }
111}
112
113pub type Acted<A, Ph, Sends, Birth, E> = Result<Actions<A, Ph, Sends, Birth>, E>;
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118 use crate::{Births, CreationKind, MailAddr};
119
120 #[test]
121 fn mapping_sends_preserves_creation_order_and_verdict() {
122 let actions: Actions<MailAddr, u8, Vec<u8>, Births<()>> = Actions::new(
123 vec![1, 2],
124 vec![
125 Create::new(3, (), CreationKind::Birth),
126 Create::new(4, (), CreationKind::replacement_of(3)),
127 ],
128 Step::Goto(7),
129 );
130
131 let mapped = actions.map_sends(|sends| sends.len());
132 assert_eq!(mapped.sends, 2);
133 assert_eq!(
134 mapped
135 .creates
136 .iter()
137 .map(|creation| creation.nonce)
138 .collect::<Vec<_>>(),
139 [3, 4]
140 );
141 assert!(matches!(mapped.become_, Step::Goto(7)));
142 }
143
144 #[test]
145 fn mapping_become_preserves_sends_and_creation_order() {
146 let actions: Actions<MailAddr, u8, Vec<u8>, Births<()>> = Actions::new(
147 vec![1, 2],
148 vec![Create::new(3, (), CreationKind::Birth)],
149 Step::Goto(7),
150 );
151
152 let mapped: Actions<MailAddr, Never, Vec<u8>, Births<()>> =
153 actions.map_become(|_| Step::Stop(Exit::Normal));
154 assert_eq!(mapped.sends, [1, 2]);
155 assert_eq!(mapped.creates[0].nonce, 3);
156 assert!(matches!(mapped.become_, Step::Stop(Exit::Normal)));
157 }
158}