Introduce a typed `ActorRequestSender` connection handle for actors and harden the `Error` type. - src/lib.rs: add `ActorRequestSender<A>` wrapping `mpsc::Sender<ActorRequest<A>>` with async `send`, `Clone`, and `From` impls; expose it via new `Handle::get_connection()` so callers hold a lightweight standalone connection to an actor - src/lib.rs: route `Handle::send` through the new sender and store `tx` as an `ActorRequestSender`; drop the `Unpin` supertrait bound from the `Actor` trait - src/error.rs: turn the `Error` type alias into a newtype struct, gate `convert_err` as `pub(crate)`, and add `From<T: AsRef<str>>` plus `ToString` impls - examples/hello.rs: switch `Greeter::spawn` to method-call syntax (`Greeter.spawn(&rt)`) to match the updated API - README.md: rename the project heading from "about" to "swactor" Signed-off-by: Zachery Aaron Shores-Chmielewski <zacheryasc@gmail.com>
46 lines
1.1 KiB
Rust
46 lines
1.1 KiB
Rust
use swactor::Actor;
|
|
use tokio::sync::oneshot;
|
|
|
|
pub enum GreeterMessage {
|
|
Name(String),
|
|
}
|
|
|
|
pub enum GreeterResponse {
|
|
Hello(String),
|
|
}
|
|
|
|
pub struct Greeter;
|
|
|
|
impl Actor for Greeter {
|
|
type Message = GreeterMessage;
|
|
type Response = GreeterResponse;
|
|
|
|
fn handle_message(&self, msg: Self::Message, tx: oneshot::Sender<Self::Response>) {
|
|
let rep = match msg {
|
|
GreeterMessage::Name(name) => GreeterResponse::Hello(format!("Hello, {name}!")),
|
|
};
|
|
|
|
if let Err(_) = tx.send(rep) {
|
|
// Greeter is not responsible for a dropped Receiver
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let rt = tokio::runtime::Builder::new_current_thread()
|
|
.build()
|
|
.expect("failed to build runtime");
|
|
let greeter = Greeter.spawn(&rt);
|
|
|
|
let response = rt
|
|
.block_on(async move {
|
|
greeter
|
|
.send(GreeterMessage::Name("world".to_string()))
|
|
.await
|
|
})
|
|
.expect("failed to get respose");
|
|
|
|
match response {
|
|
GreeterResponse::Hello(hello) => println!("{hello}"),
|
|
}
|
|
}
|