1use std::fmt;
2
3use agner_actors::{Actor, ActorID, System};
4
5#[cfg(feature = "reg")]
6use agner_reg::RegTx;
7use futures::TryFutureExt;
8
9use crate::common::gen_child_spec::args_call::{args_call0, args_call1, ArgsCallFn0, ArgsCallFn1};
10use crate::common::gen_child_spec::args_clone::{args_clone, ArgsClone};
11use crate::common::gen_child_spec::args_unique::{args_unique, ArgsUnique};
12use crate::common::gen_child_spec::traits::{CreateArgs, CreateChild};
13use crate::common::gen_child_spec::GenChildSpec;
14use crate::common::start_child::start_child;
15use crate::common::InitType;
16
17impl GenChildSpec<(), (), (), ()> {
18 pub fn new() -> Self {
19 Default::default()
20 }
21}
22
23impl Default for GenChildSpec<(), (), (), ()> {
24 fn default() -> Self {
25 GenChildSpec {
26 behaviour: (),
27 create_args: (),
28 message: Default::default(),
29 init_type: InitType::NoAck,
30
31 #[cfg(feature = "reg")]
32 reg_tx: None,
33
34 ext: (),
35 }
36 }
37}
38
39impl<X> GenChildSpec<(), (), (), X> {
40 pub fn from_ext(ext: X) -> Self {
41 GenChildSpec {
42 behaviour: (),
43 create_args: (),
44 message: Default::default(),
45 init_type: InitType::NoAck,
46
47 #[cfg(feature = "reg")]
48 reg_tx: None,
49
50 ext,
51 }
52 }
53}
54
55impl<B, A, M, X> GenChildSpec<B, A, M, X> {
56 pub fn ext(&self) -> &X {
57 &self.ext
58 }
59 pub fn ext_mut(&mut self) -> &mut X {
60 &mut self.ext
61 }
62}
63
64impl<A, M, X> GenChildSpec<(), A, M, X> {
65 pub fn behaviour<B>(self, behaviour: B) -> GenChildSpec<B, A, M, X> {
66 GenChildSpec {
67 behaviour,
68 create_args: self.create_args,
69 message: Default::default(),
70 init_type: self.init_type,
71
72 #[cfg(feature = "reg")]
73 reg_tx: self.reg_tx,
74
75 ext: self.ext,
76 }
77 }
78}
79
80impl<B, OldA, OldM, X> GenChildSpec<B, OldA, OldM, X> {
81 pub fn args_clone<A, M>(self, args: A) -> GenChildSpec<B, ArgsClone<A>, M, X>
82 where
83 B: for<'a> Actor<'a, A, M>,
84 ArgsClone<A>: CreateArgs<Input = (), Output = A>,
85 {
86 let create_args = args_clone(args);
87 GenChildSpec {
88 behaviour: self.behaviour,
89 create_args,
90 message: Default::default(),
91 init_type: self.init_type,
92
93 #[cfg(feature = "reg")]
94 reg_tx: self.reg_tx,
95
96 ext: self.ext,
97 }
98 }
99
100 pub fn args_unique<A, M>(self, args: A) -> GenChildSpec<B, ArgsUnique<A>, M, X>
101 where
102 B: for<'a> Actor<'a, Option<A>, M>,
103 ArgsUnique<A>: CreateArgs<Input = (), Output = Option<A>>,
104 {
105 let create_args = args_unique(args);
106 GenChildSpec {
107 behaviour: self.behaviour,
108 create_args,
109 message: Default::default(),
110 init_type: self.init_type,
111
112 #[cfg(feature = "reg")]
113 reg_tx: self.reg_tx,
114
115 ext: self.ext,
116 }
117 }
118
119 pub fn args_call0<F, Out, M>(self, make_args: F) -> GenChildSpec<B, ArgsCallFn0<F, Out>, M, X>
120 where
121 B: for<'a> Actor<'a, Out, M>,
122 ArgsCallFn0<F, Out>: CreateArgs<Input = (), Output = Out>,
123 {
124 let create_args = args_call0(make_args);
125 GenChildSpec {
126 behaviour: self.behaviour,
127 create_args,
128 message: Default::default(),
129 init_type: self.init_type,
130
131 #[cfg(feature = "reg")]
132 reg_tx: self.reg_tx,
133
134 ext: self.ext,
135 }
136 }
137
138 pub fn args_call1<F, In, Out, M>(
139 self,
140 make_args: F,
141 ) -> GenChildSpec<B, ArgsCallFn1<F, In, Out>, M, X>
142 where
143 B: for<'a> Actor<'a, Out, M>,
144 ArgsCallFn1<F, In, Out>: CreateArgs<Input = In, Output = Out>,
145 {
146 let create_args = args_call1(make_args);
147 GenChildSpec {
148 behaviour: self.behaviour,
149 create_args,
150 message: Default::default(),
151 init_type: self.init_type,
152
153 #[cfg(feature = "reg")]
154 reg_tx: self.reg_tx,
155
156 ext: self.ext,
157 }
158 }
159}
160
161impl<B, A, M, X> GenChildSpec<B, A, M, X> {
162 pub fn init_type<IT>(self, init_type: IT) -> Self
164 where
165 IT: Into<InitType>,
166 {
167 let init_type = init_type.into();
168 Self { init_type, ..self }
169 }
170}
171
172#[cfg(feature = "reg")]
173impl<B, A, M, X> GenChildSpec<B, A, M, X> {
174 pub fn register(self, reg_tx: RegTx) -> Self {
176 let reg_tx = Some(reg_tx);
177 Self { reg_tx, ..self }
178 }
179}
180
181impl<B, A, M, X> CreateChild for GenChildSpec<B, A, M, X>
182where
183 B: for<'a> Actor<'a, A::Output, M>,
184 A: CreateArgs,
185 B: Clone,
186 M: Unpin + Send + 'static,
187 A::Output: Send + 'static,
188{
189 type Args = A::Input;
190
191 fn create_child(
192 &mut self,
193 system: &System,
194 sup_id: ActorID,
195 args: Self::Args,
196 ) -> crate::common::StaticBoxedFuture<
197 Result<agner_actors::ActorID, crate::common::StartChildError>,
198 > {
199 let system = system.to_owned();
200 let args = self.create_args.create_args(args);
201 let behaviour = self.behaviour.to_owned();
202 let init_type = self.init_type;
203
204 #[cfg(feature = "reg")]
205 let registered_service = self.reg_tx.to_owned();
206
207 let start_child_fut = start_child(system.to_owned(), sup_id, behaviour, args, init_type)
208 .and_then(move |child_id| async move {
209 #[cfg(feature = "reg")]
210 if let Some(service) = registered_service {
211 let reg_guard = service.register(child_id);
212 system.put_data(child_id, reg_guard).await;
213 }
214
215 Ok(child_id)
216 });
217
218 Box::pin(start_child_fut)
219 }
220}
221
222impl<B, A, M, X> fmt::Debug for GenChildSpec<B, A, M, X>
223where
224 A: fmt::Debug,
225{
226 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227 f.debug_struct("CreateChildImpl")
228 .field("behaviour", &std::any::type_name::<B>())
229 .field("create_args", &self.create_args)
230 .field("init_type", &self.init_type)
231 .finish()
232 }
233}
234
235impl<B, A, M, X> Clone for GenChildSpec<B, A, M, X>
236where
237 B: Clone,
238 A: Clone,
239 X: Clone,
240{
241 fn clone(&self) -> Self {
242 Self {
243 behaviour: self.behaviour.clone(),
244 create_args: self.create_args.clone(),
245 message: Default::default(),
246 init_type: self.init_type,
247
248 #[cfg(feature = "reg")]
249 reg_tx: self.reg_tx.clone(),
250
251 ext: self.ext.clone(),
252 }
253 }
254}