messages/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![warn(
3    missing_debug_implementations,
4    rust_2018_idioms,
5    missing_docs,
6    unreachable_pub
7)]
8#![warn(clippy::pedantic)]
9#![allow(clippy::module_name_repetitions)]
10// Seems to be broken right now: https://github.com/rust-lang/rust-clippy/issues/8300
11#![allow(clippy::no_effect_underscore_binding)]
12
13//! `messages` is a runtime-agnostic actor library.
14//!
15//! It is heavily inspired by [`actix`][actix], a great actor framework.
16//!
17//! This crate can be used with any runtime, whether it popular or not.
18//! However, for the biggest one (`tokio` and `async-std`) there is an optional
19//! built-in support enabling more convenient interface (such as an automatic
20//! actor spawning).
21//!
22//! [actix]: https://crates.io/crates/actix
23//!
24//! ## Asyncness
25//!
26//! In order to provide convenient interface, this crate uses [`async_trait`](https://docs.rs/async-trait/)
27//! to declare traits with `async` methods.
28//! To make the experience more convenient, `async_trait::async_trait` macro is publicly re-exported
29//! in the [`prelude`] module.
30//!
31//! ## Examples
32//!
33//! ### With runtime features
34//!
35//! ```rust
36//! use messages::prelude::*;
37//!
38//! struct Example; // Most of the types can be an actor.
39//!
40//! // While `Actor` implementation can be customized, it is not required.
41//! #[async_trait]
42//! impl Actor for Example {}
43//!
44//! // Message handler that calculated sum of two numbers.
45//! #[async_trait]
46//! impl Handler<(u8, u8)> for Example {
47//!     type Result = u16;
48//!     async fn handle(&mut self, (a, b): (u8, u8), context: &Context<Self>) -> u16 {
49//!         (a as u16) + (b as u16)
50//!     }
51//! }
52//!
53//! // Notification handler that calculated just writes received number to stdout.
54//! #[async_trait]
55//! impl Notifiable<u8> for Example {
56//!     async fn notify(&mut self, input: u8, context: &Context<Self>) {
57//!         println!("Received number {}", input);
58//!     }
59//! }
60//!
61//! #[tokio::main]
62//! async fn main() {
63//!    let mut addr = Example.spawn();
64//!    let result = addr.send((22, 20)).await.unwrap();
65//!    assert_eq!(result, 42);
66//!    addr.notify(42).await.unwrap();
67//!    addr.stop().await;
68//!    addr.wait_for_stop().await;  
69//! }
70//! ```
71//!
72//! ### Without runtime features
73//!
74//! ```rust
75//! use messages::prelude::*;
76//!
77//! struct Ping;
78//!
79//! #[async_trait]
80//! impl Actor for Ping {}
81//!
82//! #[async_trait]
83//! impl Handler<u8> for Ping {
84//!     type Result = u8;
85//!     async fn handle(&mut self, input: u8, context: &Context<Self>) -> u8 {
86//!         input
87//!     }
88//! }
89//!
90//! #[tokio::main]
91//! async fn main() {
92//!    let context = Context::new();
93//!    let mut addr = context.address();
94//!    let actor = Ping;
95//!    // Could've been any other runtime.
96//!    let mut task_handle = tokio::spawn(context.run(actor));
97//!    let result = addr.send(42).await.unwrap();
98//!    assert_eq!(result, 42);
99//!    addr.stop().await;
100//!    addr.wait_for_stop().await;
101//!    task_handle.await.unwrap();
102//! }
103//! ```
104//!
105//! ## Main entities
106//!
107//! Main entites of this crate:
108//!
109//! - [`Actor`](crate::prelude::Actor): definition of an actor.
110//! - [`Context`](crate::prelude::Context): execution context for an actor.
111//! - [`Address`](crate::prelude::Address): address of an actor that is used to communicate with it.
112//! - Handler traits: [`Handler`](crate::prelude::Handler) and [`Notifiable`](crate::prelude::Notifiable).
113//!
114//! With runtime features enabled, there are also several more points of interest:
115//!
116//! - [`Registry`](crate::prelude::Registry): Collection of independent, unique and named actors.
117//! - [`Service`](crate::prelude::Service): Actor that can be stored in the registry.
118//! - [`Coroutine`](crate::prelude::Coroutine): Alternative to the `Handler` trait that allows
119//!   parallel message processing.
120//!
121
122/// Collection of the main types required to work with `messages` crate.
123pub mod prelude {
124    /// Convenience re-export of [`async_trait`](https://docs.rs/async-trait/) proc-macro.
125    pub use async_trait::async_trait;
126
127    pub use crate::{
128        actor::{Actor, ActorAction},
129        address::Address,
130        context::Context,
131        errors::SendError,
132        handler::{Handler, Notifiable},
133    };
134
135    super::cfg_runtime! {
136        pub use crate::registry::{Service, Registry};
137        pub use crate::actor::RuntimeActorExt;
138        pub use crate::handler::Coroutine;
139
140        /// Re-export of `JoinHandle` of chosen runtime.
141        #[cfg_attr(not(docsrs), doc(hidden))]
142        // ^ Kludge: `cargo deadlinks` finds a broken link in the tokio docs,
143        // and currently it's not possible to ignore that error.
144        // However, we don't want to completely hide this element.
145        pub use crate::runtime::JoinHandle;
146    }
147}
148
149pub mod actor;
150pub mod address;
151pub mod context;
152pub mod errors;
153pub mod handler;
154
155cfg_runtime! {
156    pub mod registry;
157}
158
159mod envelope;
160mod runtime;