use crate::{commands::CommandDescription, WhichPlugin, WhichCommandRet}; use abi_stable::{StableAbi, std_types::{RBoxError, RBox, RString, RVec}}; use std::{error::Error as ErrorTrait, fmt::{self, Display}}; use core_extensions::strings::StringExt; #[repr(u8)] #[derive(Debug, StableAbi)] pub enum Error{ /// An error produced by `serde_json::to_string`. Serialize(RBoxError,WhichCommandRet), /// An error produced by `serde_json::from_string`. Deserialize(RBoxError,WhichCommandRet), /// A deserialization error produced when trying to deserialize json /// as a particular command type. UnsupportedCommand(RBox), /// A deserialization error produced when trying to deserialize json /// as a particular return value type. UnsupportedReturnValue(RBox), /// An invalid plugin. InvalidPlugin(WhichPlugin), /// A custom error. Custom(RBoxError), /// A list of errors. Many(RVec), } /// Represents a command or return value that wasn't supported. #[repr(C)] #[derive(Debug, StableAbi)] pub struct Unsupported { /// The name of the plugin for which the command/return value wasn't supported. pub plugin_name:RString, /// The command/return value that wasn't supported. pub command_name:RString, /// A custom error. pub error:RBoxError, /// A list of the commands that the plugin supports pub supported_commands:RVec, } impl Error { pub fn unsupported_command(what:Unsupported) -> Self { Error::UnsupportedCommand(RBox::new(what)) } pub fn unsupported_return_value(what:Unsupported) -> Self { Error::UnsupportedReturnValue(RBox::new(what)) } } impl Display for Error { fn fmt(&self, f:&mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::Serialize(e, which) => { let which = match which { WhichCommandRet::Command => "command", WhichCommandRet::Return => "return value", }; writeln!(f,"Error happened while serializing the {}:\n{}\n",which,e) } Error::Deserialize(e, which) => { let which = match which { WhichCommandRet::Command => "command", WhichCommandRet::Return => "return value", }; writeln!(f,"Error happened while deserializing {}:\n{}\n", which, e) } Error::UnsupportedCommand(v) => { writeln!( f, "Plugin '{}' ooes not support this command:\n\ \t'{}'\n\ Because of this error:\n{}\n\ Supported commands:\ ", v.plugin_name, v.command_name, v.error, )?; for supported in &v.supported_commands { write!( f, "{}", format!( "\nName:\n{}\nDescription:\n{}\n\n", supported.name.left_padder(4), supported.description.left_padder(4), ).left_padder(4) )?; } Ok(()) } Error::UnsupportedReturnValue(v) => writeln!( f, "Unrecognized return value from '{}',named:\n\ \t'{}'\n\ Because of this error:\n{}\n\ ", v.plugin_name, v.command_name, v.error, ), Error::InvalidPlugin(wc) => writeln!( f, "Attempted to access a nonexistent plugin with the WhichPlugin:\n\t{:?}\n", wc ), Error::Custom(e) => Display::fmt(e, f), Error::Many(list) => { for e in list { writeln!(f,"{}",e)?; } Ok(()) } } } } impl ErrorTrait for Error{}