echo works, only external crate is serde

This commit is contained in:
Joe Ardent 2024-05-19 17:08:47 -07:00
parent 11d6734d29
commit 35e89d7c7d
4 changed files with 91 additions and 42 deletions

5
Cargo.lock generated
View file

@ -198,9 +198,8 @@ dependencies = [
name = "gg-echo"
version = "0.0.1"
dependencies = [
"async-trait",
"maelstrom-node",
"tokio",
"maelstrom-protocol",
"serde_json",
]
[[package]]

View file

@ -5,6 +5,5 @@ version.workspace = true
authors.workspace = true
[dependencies]
async-trait.workspace = true
maelstrom-node.workspace = true
tokio.workspace = true
serde_json.workspace = true
maelstrom-protocol = { path = "../maelstrom-protocol" }

View file

@ -1,29 +1,56 @@
use async_trait::async_trait;
use maelstrom::protocol::Message;
use maelstrom::{done, Node, Result, Runtime};
use std::sync::Arc;
use maelstrom_protocol as proto;
use proto::{Body, Message};
use std::io::{BufRead, Write};
#[tokio::main]
async fn main() {
let handler = Arc::new(Handler::default());
let _ = Runtime::new()
.with_handler(handler)
.run()
.await
.unwrap_or_default();
fn main() {
let mut out = std::io::stdout().lock();
let input = std::io::stdin().lock();
let mut mid = 1;
let mut node_id: String = "".to_string();
for line in input.lines() {
match line {
Ok(line) => {
if let Ok(msg) = serde_json::from_str::<proto::Message>(&line) {
let typ = &msg.body.typ;
match typ.as_str() {
"init" => {
let body = proto::init_ok(mid, msg.body.msg_id);
mid += 1;
let resp = message(&msg.src, &msg.dest, body);
node_id = msg.dest;
let resp = serde_json::to_string(&resp).unwrap();
out.write_all(resp.as_bytes()).unwrap();
out.write_all("\n".as_bytes()).unwrap();
let _ = &mut out.flush().unwrap();
}
#[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;
"echo" => {
let body = Body::from_type("echo_ok")
.with_msg_id(mid)
.with_in_reply_to(msg.body.msg_id)
.with_payload(msg.body.payload);
mid += 1;
let resp = message(&msg.src, &node_id, body);
let resp = serde_json::to_string(&resp).unwrap();
out.write_all(resp.as_bytes()).unwrap();
out.write_all("\n".as_bytes()).unwrap();
let _ = &mut out.flush().unwrap();
}
done(runtime, req)
_ => {}
}
}
}
_ => {}
}
}
}
fn message(dest: &str, src: &str, body: Body) -> Message {
Message {
dest: dest.to_owned(),
src: src.to_owned(),
body,
}
}

View file

@ -6,12 +6,12 @@ pub type Payload = Map<String, Value>;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
src: String,
dest: String,
body: Body,
pub src: String,
pub dest: String,
pub body: Body,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct Body {
#[serde(rename = "type")]
pub typ: String,
@ -23,6 +23,39 @@ pub struct Body {
pub payload: Payload,
}
impl Body {
pub fn from_type(typ: &str) -> Self {
Body {
typ: typ.to_string(),
..Default::default()
}
}
pub fn with_msg_id(self, msg_id: u64) -> Self {
let mut b = self;
b.msg_id = msg_id;
b
}
pub fn with_in_reply_to(self, in_reply_to: u64) -> Self {
let mut b = self;
b.in_reply_to = in_reply_to;
b
}
pub fn with_payload(self, payload: Payload) -> Self {
let mut b = self;
b.payload = payload;
b
}
}
pub fn init_ok(msg_id: u64, in_reply_to: u64) -> Body {
Body::from_type("init_ok")
.with_msg_id(msg_id)
.with_in_reply_to(in_reply_to)
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ErrorCode {
@ -51,15 +84,6 @@ pub enum IndefiniteError {
Crash = 13,
}
pub fn init_ok(msg_id: u64, in_reply_to: u64) -> Body {
Body {
typ: "init_ok".to_string(),
msg_id,
in_reply_to,
payload: Payload::new(),
}
}
pub fn error(msg_id: u64, in_reply_to: u64, code: ErrorCode, text: Option<&str>) -> Body {
Body {
typ: "error".to_string(),