use std::io::{Error, ErrorKind};
use crate::communication::client_argument_parser::{ClientArgumentParser, ClientArgumentParserImpl};
use crate::communication::request::RequestData;
use crate::method::method_manager::MethodManager;
use crate::method::method_structure::MethodResult;
use crate::method::response_formatter::JsonResponseFormatter;
use crate::net::tcp_reader::TcpReader;
use crate::net::tcp_writer::TcpWriter;
pub struct ClientHandlerImpl<'a> {
method_manager: &'a Box<dyn MethodManager>,
reader: Box<dyn TcpReader>,
writer: Box<dyn TcpWriter>,
}
pub trait ClientHandler {
fn handle(&mut self) -> Result<(), Error>;
}
impl ClientHandler for ClientHandlerImpl<'_> {
fn handle(&mut self) -> Result<(), Error> {
let result = self.get_request();
if result.is_err() {
self.send_error(String::from("There was an error in your JSON string"))?;
return Ok(());
}
let request = result.unwrap();
let response = self.handle_method(request)?;
self.send_response(response)?;
Ok(())
}
}
impl<'a> ClientHandlerImpl<'a> {
pub fn new(writer: Box<dyn TcpWriter>, reader: Box<dyn TcpReader>, method_manager: &'a Box<dyn MethodManager>) -> Self {
Self {
reader,
writer,
method_manager,
}
}
fn get_request(&mut self) -> Result<RequestData, Error> {
let buf = self.reader.read_line()?;
let result = serde_json::from_str(&buf);
match result {
Err(_e) => Err(Error::new(ErrorKind::Other, "Could not parse JSON")),
Ok(request_data) => Ok(request_data),
}
}
fn send_error(&mut self, message: String) -> Result<(), Error> {
self.send_response(JsonResponseFormatter::error(&message))?;
Ok(())
}
fn handle_method(&mut self, data: RequestData) -> Result<MethodResult, Error> {
let callback_option = self.method_manager.get_method_callback(&data.method_name);
if callback_option.is_none() {
return Ok(JsonResponseFormatter::error(&String::from("Method not found!")));
}
let callback = callback_option.unwrap();
let method_definition = self.method_manager.get_method(&data.method_name).unwrap();
let parser = ClientArgumentParserImpl {};
let method_arguments = parser.parse(method_definition.arguments.clone(), &data.arguments);
if method_arguments.is_err() {
return Ok(JsonResponseFormatter::error(
&method_arguments.as_ref().err().unwrap().to_string()
));
}
Ok(callback.call(method_arguments.unwrap()).to_owned())
}
fn send_response(&mut self, result: MethodResult) -> Result<(), Error> {
let result = serde_json::to_string(&result)?;
self.writer.write_line(&result)?;
Ok(())
}
}