genserver is tiny async actor framework, inspired by Elixir's GenServer. With few lines code, we do great things.
Check out the docs for more details.
First run:
console
$ cargo add genserver
Then try this code here in your crate (note the 2 features which need to be
enabled in main.rs
or lib.rs
for applications and libraries respectively):
```rust // these two features must be enabled at the crate level
use std::future::Future;
use genserver::{make_registry, GenServer};
struct MyServer { // Any state your server needs can go right // in here. We keep a registry around in case // we want to call any other servers from our // server. registry: MyRegistry, }
impl GenServer for MyServer {
// Message type for this server.
type Message = String;
// The type of the registry defined by the make_registry
attribute macro.
type Registry = MyRegistry;
// The response type for calls.
type Response = String;
// The call response type, a future, which returns Self::Response.
type CallResponse<'a> = impl Future<Output = Self::Response> + 'a;
// The cast response type, also a future, which returns unit.
type CastResponse<'a> = impl Future<Output = ()> + 'a;
fn new(registry: Self::Registry) -> Self {
// When are server is started, the registry passes a copy
// of itself here. We keep it around so we can call
// other servers from this one.
Self { registry }
}
// Calls to handle_call will block until our `Response` is returned.
// Because they return a future, we can return an async block here.
fn handle_call(&mut self, message: Self::Message) -> Self::CallResponse<'_> {
println!("handle_call received {}", message);
std::future::ready("returned from handle_call".into())
}
// Casts always return (), because they do not block callers and return
// immediately.
fn handle_cast(&mut self, message: Self::Message) -> Self::CastResponse<'_> {
println!("handle_cast received {}", message);
std::future::ready(())
}
}
myserver: MyServer
}] struct MyRegistry;
tokiotest::blockon(async { let registry = MyRegistry::start().await;
let response = registry
.call_myserver("calling myserver".into())
.await
.unwrap();
registry
.cast_myserver("casting to myserver".into())
.await
.unwrap();
}); ```