echo works, only external crate is serde
This commit is contained in:
parent
11d6734d29
commit
35e89d7c7d
4 changed files with 91 additions and 42 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -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]]
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
Loading…
Reference in a new issue