You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.2 KiB
Rust
73 lines
2.2 KiB
Rust
use crate::rpc::{Command, Request, Answer, AnswerResult, AnswerError, Response};
|
|
use std::fmt::{Display, Formatter};
|
|
use std::fmt;
|
|
use std::error::Error;
|
|
|
|
#[derive(Debug, Default)]
|
|
pub struct CommandCenter {
|
|
id: u64,
|
|
}
|
|
|
|
impl CommandCenter {
|
|
pub fn write_command<R: Request>(&mut self, request: R) -> Result<(u64, String), anyhow::Error> {
|
|
let command = Command {
|
|
id: self.id,
|
|
data: request.into_enum(),
|
|
};
|
|
|
|
self.id += 1;
|
|
|
|
let mut str = serde_json::to_string(&command)?;
|
|
str.push('\n');
|
|
Ok((command.id, str))
|
|
}
|
|
|
|
pub fn write_answer<R: Response>(request: &Command, answer: Result<R, anyhow::Error>) -> Result<String, anyhow::Error> {
|
|
let answer = Answer {
|
|
id: request.id,
|
|
data: match answer {
|
|
Ok(data) => AnswerResult::Ok(data),
|
|
Err(err) => AnswerResult::Error(AnswerError {
|
|
error: format!("{:?}", err)
|
|
})
|
|
},
|
|
};
|
|
|
|
let mut str = serde_json::to_string(&answer)?;
|
|
str.push('\n');
|
|
Ok(str)
|
|
}
|
|
|
|
pub fn read_command(request: &str) -> Result<Command, anyhow::Error> {
|
|
serde_json::from_str(request).map_err(From::from)
|
|
}
|
|
|
|
pub fn read_answer<R: Request>(answer: &str) -> Result<(u64, R::Response), CommandError> {
|
|
log::debug!("Reading answer: {}", answer);
|
|
let answer_obj: Answer<R::Response> = serde_json::from_str(answer).map_err(|err| CommandError::InternalError(err.into()))?;
|
|
|
|
match answer_obj.data {
|
|
AnswerResult::Error(err) => Err(CommandError::AnswerError(answer_obj.id, err)),
|
|
AnswerResult::Ok(data) => Ok((answer_obj.id, data))
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum CommandError {
|
|
AnswerError(u64, AnswerError),
|
|
InternalError(anyhow::Error),
|
|
}
|
|
|
|
impl Display for CommandError {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
CommandError::AnswerError(idx, err) => {
|
|
write!(f, "{}\n(rpc call {})", err.error, idx)
|
|
}
|
|
CommandError::InternalError(err) => err.fmt(f)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Error for CommandError {} |