echo/echo.rs
1//! Echo Actor Example
2//!
3//! This example demonstrates how to implement the simplest possible Actor,
4//! illustrating the following features:
5//! - Implementing the Actor trait
6//! - Processing Inbox messages
7//! - Sending messages to the Actor
8//! - Correctly releasing the Outbox
9use acty::{Actor, ActorExt, AsyncClose};
10use futures::{Stream, StreamExt};
11use std::pin::pin;
12
13/// The simplest Echo Actor
14///
15/// This Actor processes messages of type `String` and prints them to standard output.
16/// Note: This Actor has no state fields, demonstrating only the basic usage.
17struct Echo;
18
19/// Implements the `Actor` trait, with message type `String`
20///
21/// When a message is received in the Inbox, it is printed line by line to standard output.
22impl Actor for Echo {
23 type Message = String;
24
25 async fn run(self, inbox: impl Stream<Item = Self::Message> + Send) {
26 // Pin the inbox to the stack for asynchronous iteration.
27 // If it needed to be passed across function boundaries, Box::pin could be used
28 // to pin it to the heap (with a small allocation overhead).
29 let mut inbox = pin!(inbox);
30
31 // Asynchronously iterate through every message in the inbox
32 while let Some(msg) = inbox.next().await {
33 println!("echo: {}", msg);
34 }
35 }
36}
37
38#[tokio::main]
39async fn main() {
40 // Launch the actor and obtain the associated outbox
41 let echo = Echo.start();
42
43 // Send messages to the Actor
44 // send returns a Result, returning Err if the Actor has shut down
45 // We use unwrap_or(()) here to ignore potential errors
46 echo.send("Hello".to_string()).unwrap_or(());
47 echo.send("World".to_string()).unwrap_or(());
48 echo.send("!".to_string()).unwrap_or(());
49
50 // Close the outbox, unbinding it from the actor.
51 // This ensures the actor finishes naturally after processing all messages.
52 echo.close().await;
53}