use base::Result;
use base::data::Datable;
use app::{Request, Response};
use app::{RequestChannel, ResponseSender};
use app::Logger;
pub trait App<A, P, R>
where A: Ord + Datable,
P: Datable,
R: Datable,
Self: 'static + Sized + Send + Sync + Logger
{
fn address(&self) -> A;
fn request_channel(&self) -> RequestChannel<A, P>;
fn response_sender(&self) -> ResponseSender<A, R>;
fn exec(&mut self, req: &Request<A, P>)
-> Result<Response<A, R>>;
fn log_result<T: Sized>(&self, res: &Result<T>);
fn run(&mut self) {
let sender = self.response_sender();
loop {
for req in self.request_channel().receiver {
let res = self.exec(&req)
.or_else(|e| {
let err = Err(format!("{:?}", e));
self.log_result(&err);
err
})
.and_then(|res| {
sender
.send(res)
.map_err(|e| format!("{:?}", e))
});
self.log_result(&res);
res.unwrap();
}
}
}
}