Added return data to `Action`. It is pretty simple right now, because we always expect something to return
This commit is contained in:
parent
5e6dfd35c1
commit
055fb6e489
|
@ -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(())
|
||||
}));
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue