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" name = "gg-echo"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"async-trait", "maelstrom-protocol",
"maelstrom-node", "serde_json",
"tokio",
] ]
[[package]] [[package]]

View file

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

View file

@ -1,29 +1,56 @@
use async_trait::async_trait; use maelstrom_protocol as proto;
use maelstrom::protocol::Message; use proto::{Body, Message};
use maelstrom::{done, Node, Result, Runtime}; use std::io::{BufRead, Write};
use std::sync::Arc;
#[tokio::main] fn main() {
async fn main() { let mut out = std::io::stdout().lock();
let handler = Arc::new(Handler::default()); let input = std::io::stdin().lock();
let _ = Runtime::new()
.with_handler(handler) let mut mid = 1;
.run()
.await let mut node_id: String = "".to_string();
.unwrap_or_default();
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();
} }
"echo" => {
#[derive(Clone, Default)] let body = Body::from_type("echo_ok")
struct Handler {} .with_msg_id(mid)
.with_in_reply_to(msg.body.msg_id)
#[async_trait] .with_payload(msg.body.payload);
impl Node for Handler { mid += 1;
async fn process(&self, runtime: Runtime, req: Message) -> Result<()> { let resp = message(&msg.src, &node_id, body);
if req.get_type() == "echo" { let resp = serde_json::to_string(&resp).unwrap();
let echo = req.body.clone().with_type("echo_ok"); out.write_all(resp.as_bytes()).unwrap();
return runtime.reply(req, echo).await; 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)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message { pub struct Message {
src: String, pub src: String,
dest: String, pub dest: String,
body: Body, pub body: Body,
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct Body { pub struct Body {
#[serde(rename = "type")] #[serde(rename = "type")]
pub typ: String, pub typ: String,
@ -23,6 +23,39 @@ pub struct Body {
pub payload: Payload, 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)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)] #[serde(untagged)]
pub enum ErrorCode { pub enum ErrorCode {
@ -51,15 +84,6 @@ pub enum IndefiniteError {
Crash = 13, 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 { pub fn error(msg_id: u64, in_reply_to: u64, code: ErrorCode, text: Option<&str>) -> Body {
Body { Body {
typ: "error".to_string(), typ: "error".to_string(),