Hi,
Let me brag about a new Rust client that I did for Maelstrom that supports rpc() and kv(). For all interested folks, you are welcome at https://crates.io/crates/maelstrom-node.
Forgive me if something is not perfect. I wanted to get some Rust experience.
Sample for echo workload:
use async_trait::async_trait;
use maelstrom::protocol::Message;
use maelstrom::{Node, Result, Runtime};
use std::sync::Arc;
pub(crate) fn main() -> Result<()> {
Runtime::init(try_main())
}
async fn try_main() -> Result<()> {
let handler = Arc::new(Handler::default());
Runtime::new().with_handler(handler).run().await
}
#[derive(Clone, Default)]
struct Handler {}
#[async_trait]
impl Node for Handler {
async fn process(&self, runtime: Runtime, req: Message) -> Result<()> {
if req.get_type() == "echo" {
let echo = req.body.clone().with_type("echo_ok");
return runtime.reply(req, echo).await;
}
done(runtime, message)
}
}
And this is how RPC calls looks like that interact with the KV storages - lin-kv workload:
#[async_trait]
impl Node for Handler {
async fn process(&self, runtime: Runtime, req: Message) -> Result<()> {
let (ctx, _handler) = Context::new();
let msg: Result<Request> = req.body.as_obj();
match msg {
Ok(Request::Read { key }) => {
let value = self.s.get(ctx, key.to_string()).await?;
return runtime.reply(req, Request::ReadOk { value }).await;
}
Ok(Request::Write { key, value }) => {
self.s.put(ctx, key.to_string(), value).await?;
return runtime.reply(req, Request::WriteOk {}).await;
}
Ok(Request::Cas { key, from, to, put }) => {
self.s.cas(ctx, key.to_string(), from, to, put).await?;
return runtime.reply(req, Request::CasOk {}).await;
}
_ => done(runtime, req),
}
}
}
fn handler(runtime: Runtime) -> Handler {
Handler { s: lin_kv(runtime) }
}