1
0

refactored library

This commit is contained in:
Ishan Jain 2024-01-03 13:00:48 +05:30
parent 74107a9c68
commit 7ff21c5ada
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27
2 changed files with 61 additions and 57 deletions

View File

@ -2,36 +2,53 @@ pub mod types;
use crate::types::Message; use crate::types::Message;
use std::{ use std::{
collections::HashMap, collections::HashMap,
io::{stdin, stdout, BufRead, BufReader, Error as IoError, Stdin, Stdout, Write}, io::{stdin, stdout, BufRead, Error as IoError, Stdin, Stdout, Write},
rc::Rc, rc::Rc,
sync::{Arc, Mutex},
}; };
pub struct Malestorm<'a> { pub struct Malestorm<'a> {
stdin: Stdin, io: MalestormIo,
pub stdout: Stdout, pub handlers: HashMap<&'a str, Box<dyn Fn(Message, Rc<Malestorm>)>>,
}
pub handlers: HashMap<&'a str, Box<dyn Fn(Message)>>, struct MalestormIo {
stdin: Stdin,
stdout: Stdout,
} }
impl<'a> Default for Malestorm<'a> { impl<'a> Default for Malestorm<'a> {
fn default() -> Self { fn default() -> Self {
Self { Self {
io: MalestormIo {
stdin: stdin(), stdin: stdin(),
stdout: stdout(), stdout: stdout(),
},
handlers: HashMap::new(), handlers: HashMap::new(),
} }
} }
} }
impl MalestormIo {
fn write(&self, buf: &[u8]) -> Result<(), IoError> {
let mut writer = self.stdout.lock();
writer.write_all(buf)?;
writer.flush()
}
fn read_line(&self, buf: &mut Vec<u8>) -> Result<usize, IoError> {
let mut reader = self.stdin.lock();
reader.read_until(b'\n', buf)
}
}
impl<'a> Malestorm<'a> { impl<'a> Malestorm<'a> {
pub fn run(self) { pub fn run(self) {
let mut reader = BufReader::new(self.stdin); let program = Rc::new(self);
let mut buf = String::new();
let mut buf = Vec::new();
loop { loop {
let read = match reader.read_line(&mut buf) { let read = match program.io.read_line(&mut buf) {
Ok(v) => v, Ok(v) => v,
Err(e) => panic!("{:?}", e), Err(e) => panic!("{:?}", e),
}; };
@ -40,7 +57,7 @@ impl<'a> Malestorm<'a> {
continue; continue;
} }
let message: Message = match serde_json::from_str(&buf) { let message: Message = match serde_json::from_slice(&buf) {
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {
eprintln!("error in parsing input: {:?}", e); eprintln!("error in parsing input: {:?}", e);
@ -50,7 +67,9 @@ impl<'a> Malestorm<'a> {
let mtype = message.body.message_type.clone(); let mtype = message.body.message_type.clone();
let handler = match self.handlers.get(&mtype.as_str()) { let pc = program.clone();
let handler = match program.handlers.get(&mtype.as_str()) {
Some(v) => v, Some(v) => v,
None => { None => {
eprintln!("no handler found for {}", message.body.message_type); eprintln!("no handler found for {}", message.body.message_type);
@ -58,26 +77,26 @@ impl<'a> Malestorm<'a> {
} }
}; };
handler(message); handler(message, pc);
} }
} }
pub fn register(&mut self, name: &'a str, func: impl Fn(Message) + 'a + 'static) { pub fn register(
self.handlers &mut self,
.insert(name, Box::new(move |msg: Message| func(msg))); name: &'a str,
func: impl Fn(Message, Rc<Malestorm>) + 'a + 'static,
) {
self.handlers.insert(name, Box::new(func));
} }
pub fn send(&self, msg: Message) -> Result<(), IoError> { pub fn reply(&self, mut msg: Message) -> Result<(), IoError> {
// Before replying, Swap src / dst in original message
// Add the correct value for in_reply_to
std::mem::swap(&mut msg.src, &mut msg.dest);
msg.body.in_reply_to = msg.body.msg_id;
let out = serde_json::to_vec(&msg)?; let out = serde_json::to_vec(&msg)?;
match self.write(&out) { self.io.write(&out).map(|_| Ok(()))?
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}
fn write(&self, buf: &[u8]) -> Result<usize, IoError> {
let mut writer = self.stdout.lock();
writer.write(buf)
} }
} }

View File

@ -1,44 +1,29 @@
#![allow(special_module_name)] #![allow(special_module_name)]
use std::{ use std::rc::Rc;
io::{stdout, Write},
rc::Rc,
sync::{Arc, Mutex},
};
use distributed_systems_flyio::{ use distributed_systems_flyio::{
types::{EchoMessage, Message, MessageBody}, types::{EchoMessage, Message},
Malestorm, Malestorm,
}; };
fn main() { fn main() {
let mut program = Malestorm::default(); let mut program = Malestorm::default();
let stdout = Arc::new(stdout()); program.register("echo", |mut msg: Message, program: Rc<Malestorm>| {
let message_body: EchoMessage =
let handlers = &mut program.handlers; serde_json::from_value(msg.body.message_body).expect("error in parsing message body");
handlers.insert(
"echo",
Box::new(move |mut msg: Message| {
let message_body: EchoMessage = serde_json::from_value(msg.body.message_body)
.expect("error in parsing message body");
msg.body.message_type = "echo_ok".into(); msg.body.message_type = "echo_ok".into();
msg.body.message_body = serde_json::to_value(message_body).unwrap(); msg.body.message_body = serde_json::to_value(message_body).unwrap();
match serde_json::to_vec(&msg).map(|buf| { match program.reply(msg) {
let mut writer = stdout.lock();
writer.write_all(&buf).expect("error in writing content");
writer.flush()
}) {
Ok(_) => (), Ok(_) => (),
Err(e) => { Err(e) => {
eprintln!("error in writing response: {}", e); eprintln!("error in writing response: {}", e);
} }
}; }
}), });
);
program.run(); program.run();
} }