atticus/
lib.rs

1//! atticus: A simple implementation of an actor in Tokio.
2//!
3//! Actors provide a way to invoke messages or requests among asynchronous tasks.  This avoids the
4//! need to use `Arc<Mutex<T>>` instances of an object to be passed around so shared state can be
5//! made. It makes use of channels to exchange data.
6//!
7//! Actors aim to clarify ownership data structures.
8//!
9//! Create an actor by implementing the [Actor] trait.
10//!
11//! ```rust
12//! use atticus::Actor;
13//! use async_trait::async_trait;
14//!
15//! struct IntToString;
16//!
17//! #[async_trait]
18//! impl Actor for IntToString {
19//!    type Request = i32;
20//!    type Response = String;
21//!    async fn handle(&mut self, request: Self::Request) -> Option<Self::Response> {
22//!        Some(request.to_string())
23//!    }
24//! }
25//!
26//! #[tokio::main(flavor="current_thread")]
27//! async fn main() {
28//!    // Spawn using [actor::run]
29//!    let handle = atticus::actor::run(IntToString{}, 1);
30//!
31//!    // Send a request to convert 5 to String.
32//!    let response = handle.requestor.request(5).await;
33//!
34//!    assert!(response.is_ok());
35//!    assert_eq!(response.unwrap(), Some(String::from("5")));
36//! }
37//!
38//! ```
39
40#![warn(missing_docs)]
41#![deny(rustdoc::broken_intra_doc_links)]
42
43/// Defines the interface on how to glue in your custom [Actor]
44pub mod actor;
45
46/// Defines the error types that this crate provides.
47pub mod error;
48
49pub use actor::{run, Actor, Handle, Requestor};
50pub use error::Error;
51
52/// Re-export tokio symbols that we use
53pub use tokio::{sync::mpsc, task::JoinHandle};
54
55#[cfg(test)]
56mod tests {
57    use async_trait::async_trait;
58
59    use crate::actor::*;
60    use crate::Error;
61
62    #[derive(Debug)]
63    struct NormalType;
64
65    #[async_trait]
66    impl Actor for NormalType {
67        type Request = usize;
68        type Response = bool;
69
70        async fn handle(&mut self, _message: Self::Request) -> Option<Self::Response> {
71            unreachable!()
72        }
73    }
74
75    const fn is_send_sync<T: Sized + Send + Sync + Unpin>() {}
76    const fn impls_or_derives_debug<Debug>() {}
77
78    #[test]
79    const fn test_public_types() {
80        is_send_sync::<Requestor<NormalType, NormalType>>();
81        is_send_sync::<Handle<NormalType>>();
82        is_send_sync::<Error>();
83    }
84
85    #[test]
86    const fn test_impls_debug() {
87        impls_or_derives_debug::<Requestor<NormalType, NormalType>>();
88        impls_or_derives_debug::<Handle<NormalType>>();
89        impls_or_derives_debug::<Error>();
90    }
91}