agner_sup/common/gen_child_spec/
gen_child_spec_impl.rs

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    /// Specify child's [init-type](crate::common::InitType)
163    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    /// [Register the actor](agner_reg::Service) when it starts
175    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}