Added return data to `Action`. It is pretty simple right now, because we always expect something to return

This commit is contained in:
Martin Slot 2023-11-28 08:43:31 +01:00
parent 5e6dfd35c1
commit 055fb6e489
4 changed files with 33 additions and 17 deletions

View File

@ -86,8 +86,13 @@ impl Host {
Err(e) => return Err(HostError::DecodeError),
};
let router = router.lock().unwrap();
router.call(payload.route, &bytes);
let router = router.lock().unwrap(); // TODO: do we want to handle a potential deadlock? Is this even the correct rust pattern for locking?
let return_data = router.call(payload.route, &bytes);
match stream.write(&return_data) {
Ok(_) => {} // do nothing for now
Err(_) => return Err(HostError::WriteError),
}
}
Ok(())
}));

View File

@ -15,20 +15,20 @@ impl Router {
self.router_map.insert(route.to_string(), action);
}
pub fn call(&self, route: String, data: &Vec<u8>) {
pub fn call(&self, route: String, data: &Vec<u8>) -> Vec<u8> {
let action = self.router_map.get(&route);
let action = match action {
None => return,
None => return [0u8; 0].to_vec(), // TODO: we need to make the return of call an Option, with either something or nothing, so the caller can decide what to do
Some(a) => a,
};
action.work(&data);
action.work(&data)
}
}
pub trait Action: Send + Sync {
fn work(&self, data: &Vec<u8>);
fn work(&self, data: &Vec<u8>) -> Vec<u8>; // TODO: this always needs to return, which isn't always the case: something could go wrong. Make it more "errorable"
}
mod tests {
use super::{Action, Router};
@ -36,7 +36,9 @@ mod tests {
struct TestAction;
impl Action for TestAction {
fn work(&self, data: &Vec<u8>) {}
fn work(&self, data: &Vec<u8>) -> Vec<u8> {
[0u8; 1].to_vec()
}
}
#[test]
fn create_router_with_one_action() {

View File

@ -36,20 +36,20 @@ impl StreamClient {
match stream.read(&mut buf) {
// TODO: what happens if there is nothing to read?
Ok(_) => Ok(buf.to_vec()),
Err(_) => Err(StreamClientError::ReadError),
Err(_) => Err(StreamClientError::Read),
}
}
Err(_) => Err(StreamClientError::WriteError),
Err(_) => Err(StreamClientError::Write),
},
Err(_) => Err(StreamClientError::ConnectError),
Err(_) => Err(StreamClientError::Connect),
}
}
}
mod errors {
pub enum StreamClientError {
ConnectError,
WriteError,
ReadError,
Connect,
Write,
Read,
}
}

View File

@ -1,10 +1,11 @@
extern crate commander_host;
extern crate kernel;
use std::{thread, time};
use std::{str, thread, time};
use commander_host::{ConnectOptions, Host};
use commander_host::Host;
use kernel::router::Action;
use kernel::tcp::ConnectOptions;
#[test]
fn does_not_start_when_calling_stop_before_start() {
@ -95,7 +96,15 @@ fn can_add_one_action_and_start_and_call_it() {
struct ServerTestAction;
impl Action for ServerTestAction {
fn work(&self, data: &Vec<u8>) {
println!("hello from ServerTestAction");
fn work(&self, data: &Vec<u8>) -> Vec<u8> {
let got = match str::from_utf8(data) {
Ok(from_raw) => from_raw,
Err(_) => {
panic!("Could not read input. Invalid utf8 :(")
}
};
let return_string = format!("Hello from ServerTestAction. Got: {}", got);
return_string.as_bytes().to_vec()
}
}