diff --git a/Cargo.lock b/Cargo.lock index 4cb5376..6255c6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,9 +198,8 @@ dependencies = [ name = "gg-echo" version = "0.0.1" dependencies = [ - "async-trait", - "maelstrom-node", - "tokio", + "maelstrom-protocol", + "serde_json", ] [[package]] diff --git a/gg-echo/Cargo.toml b/gg-echo/Cargo.toml index 842c03c..26c9be9 100644 --- a/gg-echo/Cargo.toml +++ b/gg-echo/Cargo.toml @@ -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" } diff --git a/gg-echo/src/main.rs b/gg-echo/src/main.rs index 6be49c6..18c8ff9 100644 --- a/gg-echo/src/main.rs +++ b/gg-echo/src/main.rs @@ -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(); -#[derive(Clone, Default)] -struct Handler {} + let mut mid = 1; -#[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; + let mut node_id: String = "".to_string(); + + for line in input.lines() { + match line { + Ok(line) => { + if let Ok(msg) = serde_json::from_str::(&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" => { + 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, } } diff --git a/maelstrom-protocol/src/lib.rs b/maelstrom-protocol/src/lib.rs index 950e422..7df7cca 100644 --- a/maelstrom-protocol/src/lib.rs +++ b/maelstrom-protocol/src/lib.rs @@ -6,12 +6,12 @@ pub type Payload = Map; #[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(),