1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! # Motivation
//!
//! In async Rust, you often find yourself spawning tasks and creating channels to communicate between them.
//! This can become cumbersome in larger projects and complicated when supporting multiple message types.
//! An [`Actor`] *is* a task that can receive and handle [messages](`Message`) and store internal state.
//!
//!
//! ## Simple Example
//!
//! You can send messages to an actor without expecting a response.
//!
//! ```rust
//! # use hannibal::prelude::*;
//! #[derive(Actor)]
//! struct Greeter(&'static str);
//!
//! #[message]
//! struct Greet(&'static str);
//!
//! impl Handler<Greet> for Greeter {
//! async fn handle(&mut self, _ctx: &mut Context<Self>, msg: Greet) {
//! println!(
//! "[Actor {me}] Hello {you}, my name is {me}",
//! me = self.0,
//! you = msg.0,
//! );
//! }
//! }
//!
//! # #[hannibal::main]
//! # async fn main() {
//! let mut addr = Greeter("Caesar").spawn();
//!
//! addr.send(Greet("Hannibal")).await.unwrap();
//! # }
//! ```
//!
//! You can also call the actor and get a response.
//!
//! ```rust
//! # use hannibal::prelude::*;
//! #[derive(Actor)]
//! struct Calculator();
//!
//! #[message(response = i32)]
//! struct Add(i32, i32);
//!
//! impl Handler<Add> for Calculator {
//! async fn handle(&mut self, _ctx: &mut Context<Self>, msg: Add) -> i32 {
//! msg.0 + msg.1
//! }
//! }
//!
//! # #[hannibal::main]
//! # async fn main() {
//! let mut addr = Calculator().spawn();
//!
//! let addition = addr.call(Add(1, 2)).await;
//!
//! println!("The Actor Calculated: {:?}", addition);
//! # }
//! ```
//!
//! ## Runtime behavior
//! Actors can also be used to handle [Streams](`futures::Stream`) by implementing [`StreamHandler`],
//! they can be configured to enforce timeouts and use bounded or unbounded channels under the hood.
//! Take a look at [`hannibal::setup_actorer`](`builder`)
//! to see how to configure an actor's runtime behavior and how to launch them on streams.
// Runtime features are mutually exclusive
compile_error!;
pub use ;
// TODO: flatten module structure
pub use ;
pub use ;
pub use Broker;