tokactor/
anonymous.rs

1use std::{future::Future, marker::PhantomData};
2
3use crate::{Actor, Ask, AskResult, AsyncAsk, Ctx, Handler, Message};
4
5pub struct AnonymousActor<In: Message, Out: Message, F: Fn(In) -> Out> {
6    f: Option<F>,
7    _in: PhantomData<In>,
8    _out: PhantomData<Out>,
9}
10
11impl<In, Out, F> From<F> for AnonymousActor<In, Out, F>
12where
13    In: Message,
14    Out: Message,
15    F: Fn(In) -> Out + Send + Sync + 'static,
16{
17    fn from(f: F) -> Self {
18        Self {
19            f: Some(f),
20            _in: PhantomData,
21            _out: PhantomData,
22        }
23    }
24}
25
26impl<In, Out, F> Actor for AnonymousActor<In, Out, F>
27where
28    In: Message,
29    Out: Message,
30    F: Fn(In) -> Out + Send + Sync + 'static,
31{
32    fn name() -> &'static str {
33        "AnoymousFnActor"
34    }
35
36    fn mailbox_size() -> usize {
37        1
38    }
39}
40
41impl<In, F> Handler<In> for AnonymousActor<In, (), F>
42where
43    In: Message,
44    F: Fn(In) + Send + Sync + 'static,
45{
46    fn handle(&mut self, message: In, _: &mut Ctx<Self>) {
47        let f = self.f.take().unwrap();
48        (f)(message);
49    }
50}
51
52impl<In, Out, F> Ask<In> for AnonymousActor<In, Out, F>
53where
54    In: Message,
55    Out: Message,
56    F: Fn(In) -> Out + Send + Sync + 'static,
57{
58    type Result = Out;
59
60    fn handle(&mut self, message: In, _: &mut Ctx<Self>) -> AskResult<Out> {
61        let f = self.f.take().unwrap();
62        AskResult::Reply((f)(message))
63    }
64}
65
66impl<In, Out, Fut, F> AsyncAsk<In> for AnonymousActor<In, Fut, F>
67where
68    In: Message,
69    Out: Message,
70    F: Fn(In) -> Fut + Send + Sync + 'static,
71    for<'a> Fut: Future<Output = Out> + Send + Sync + 'a,
72{
73    type Output = Out;
74    type Future<'a> = Fut;
75
76    fn handle<'a>(&'a mut self, message: In, _: &mut Ctx<Self>) -> Self::Future<'a> {
77        let f = self.f.take().unwrap();
78        (f)(message)
79    }
80}
81
82#[cfg(test)]
83mod test {
84
85    // use crate::{util::Workflow, utils::workflow::WorkflowBase, Actor, Ask, Message};
86
87    // struct Response {
88    //     rx: tokio::sync::oneshot::Receiver<Increment>,
89    // }
90
91    // struct Increment(usize);
92
93    // async fn increment(msg: Increment) -> Increment {
94    //     Increment(msg.0 + 1)
95    // }
96
97    // use crate::{Actor, Handler, Message};
98
99    // trait All: Send + Sync + 'static {}
100
101    // struct GenericRunner<A: All, B: All, C: All> {
102    //     a: A,
103    //     b: B,
104    //     c: C,
105    // }
106
107    // impl<A: All, B: All, C: All> Actor for GenericRunner<A, B, C> {}
108
109    // impl<A: All + Message, B: All, C: All> Handler<A> for GenericRunner<A, B, C> {
110    //     fn handle(&mut self, message: A, context: &mut crate::Ctx<Self>) {
111    //         println!("Get a message for A")
112    //     }
113    // }
114
115    // impl Actor for Runner {}
116
117    // impl Ask<Increment> for Runner {
118    //     type Result = Response;
119    //     fn handle(&mut self, message: Increment, context: &mut crate::Ctx<Self>) -> Self::Result {
120    //         let (tx, rx) = tokio::sync::oneshot::channel();
121    //         let future = increment
122    //             .then(increment)
123    //             .then(increment)
124    //             .then(increment)
125    //             .then(increment)
126    //             .run(message);
127
128    //         let handle = context.anonymous(future);
129    //     }
130    // }
131
132    // #[tokio::test]
133    // async fn test() {
134    //     let runner = Runner;
135    //     let address = runner.start();
136    //     address.try_send(Increment(0));
137    //     let output = assert_eq!(output.0, 5);
138    // }
139}