use std::{any::type_name, io};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum RobotException {
#[error("none")]
NoException,
#[error("Model exception: {0}")]
ModelException(String),
#[error("Network exception: {0}")]
NetworkError(String),
#[error(
"Incompatible version: server version {server_version}, client version {client_version}"
)]
IncompatibleVersionException {
server_version: u64,
client_version: u64,
},
#[error("Realtime exception: {0}")]
RealtimeException(String),
#[error("Unprocessable instruction error: {0}")]
UnprocessableInstructionError(String),
#[error("Conflicting instruction error: {0}")]
ConflictingInstruction(String),
#[error("Command exception: {0}")]
CommandException(String),
#[error("Invalid instruction error: {0}")]
InvalidInstruction(String),
#[error("Deserialize error: {0}")]
DeserializeError(String),
#[error("Invalid FFI data error: {0}")]
InvalidFFIData(String),
#[error("UnWarp error: {0}")]
UnWarpError(String),
}
pub type RobotResult<T> = Result<T, RobotException>;
impl From<io::Error> for RobotException {
fn from(e: io::Error) -> Self {
RobotException::NetworkError(e.to_string())
}
}
impl From<anyhow::Error> for RobotException {
fn from(e: anyhow::Error) -> Self {
RobotException::CommandException(e.to_string())
}
}
pub fn deserialize_error<T, E>(data: &str) -> impl FnOnce(E) -> RobotException {
move |_| {
RobotException::DeserializeError(format!("exception {}, find {}", type_name::<T>(), data))
}
}
pub fn invalid_ffi<T: std::fmt::Debug>(data: T) -> RobotException {
RobotException::InvalidFFIData(format!("exception {}, find {:?}", type_name::<T>(), data))
}
#[cfg(feature = "to_py")]
use pyo3::exceptions::PyException;
#[cfg(feature = "to_py")]
impl From<RobotException> for pyo3::PyErr {
fn from(e: RobotException) -> Self {
PyException::new_err(e.to_string())
}
}