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"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"maelstrom-node",
|
||||
"tokio",
|
||||
"maelstrom-protocol",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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::<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" => {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Reference in a new issue