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}