use core::{str, fmt, convert};
pub mod request;
pub mod response;
#[derive(Clone)]
pub enum Request<'a> {
Login(request::Login<'a>),
Get(request::Get<'a>),
DBstats
}
impl<'a> convert::From<request::Login<'a>> for Request<'a> {
fn from(login: request::Login<'a>) -> Self {
Request::Login(login)
}
}
impl<'a> convert::From<request::Get<'a>> for Request<'a> {
fn from(get: request::Get<'a>) -> Self {
Request::Get(get)
}
}
impl<'a> fmt::Display for Request<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Request::Login(ref login) => write!(f, "{}\x04", login),
Request::Get(ref get) => write!(f, "{}\x04", get),
Request::DBstats => write!(f, "dbstats\x04")
}
}
}
#[derive(Debug, Clone)]
pub enum Response {
Ok,
Results(response::Results),
DBstats(response::DBstats),
Error(response::VndbError)
}
impl convert::From<response::Results> for Response {
fn from(results: response::Results) -> Self {
Response::Results(results)
}
}
impl convert::From<response::DBstats> for Response {
fn from(stats: response::DBstats) -> Self {
Response::DBstats(stats)
}
}
impl convert::From<response::VndbError> for Response {
fn from(error: response::VndbError) -> Self {
Response::Error(error)
}
}
impl Response {
pub fn from_str(msg: &str) -> Result<Self, ResponseParseError> {
let mut split_msg = msg.splitn(2, ' ');
let command = match split_msg.next() {
Some(command) => command,
None => return Err(ResponseParseError::EmptyResponse),
};
match command {
"ok" => Ok(Response::Ok),
"results" => match split_msg.next() {
Some(results) => match response::Results::from_str(results) {
Ok(results) => Ok(Response::Results(results)),
Err(error) => Err(ResponseParseError::InvalidResults(error)),
},
None => Err(ResponseParseError::EmptyResults),
},
"dbstats" => match split_msg.next() {
Some(dbstats) => match serde_json::from_str(dbstats) {
Ok(dbstats) => Ok(Response::DBstats(dbstats)),
Err(error) => Err(ResponseParseError::InvalidDbStats(error)),
},
None => Err(ResponseParseError::EmptyDbStats),
},
"error" => match split_msg.next() {
Some(error) => match serde_json::from_str(error) {
Ok(error) => Ok(Response::Error(error)),
Err(error) => Err(ResponseParseError::InvalidError(error)),
},
None => Err(ResponseParseError::EmptyDbStats),
}
_ => Err(ResponseParseError::UnknownComamnd),
}
}
}
#[derive(Debug)]
pub enum ResponseParseError {
EmptyResponse,
EmptyResults,
EmptyDbStats,
EmptyError,
InvalidResults(serde_json::Error),
InvalidDbStats(serde_json::Error),
InvalidError(serde_json::Error),
UnknownComamnd,
}
impl fmt::Display for ResponseParseError {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
ResponseParseError::EmptyResponse => fmt.write_str("VNDB sent empty response."),
ResponseParseError::EmptyResults => fmt.write_str("VNDB sent Results with no payload."),
ResponseParseError::EmptyDbStats => fmt.write_str("VNDB sent DBstats with no payload."),
ResponseParseError::EmptyError => fmt.write_str("VNDB sent Error with no payload."),
ResponseParseError::InvalidResults(ref error) => write!(fmt, "VNDB sent invalid JSON in Results: {}", error),
ResponseParseError::InvalidDbStats(ref error) => write!(fmt, "VNDB sent invalid JSON in DBstats: {}", error),
ResponseParseError::InvalidError(ref error) => write!(fmt, "VNDB sent invalid JSON in Error: {}", error),
ResponseParseError::UnknownComamnd => fmt.write_str("VNDB sent unknown command"),
}
}
}
impl std::error::Error for ResponseParseError {}