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