Files
simple-rust-tests/__ffi/abi_stable_crates/interface/src/error.rs
2020-12-27 14:51:24 +08:00

127 lines
4.2 KiB
Rust

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<Unsupported>),
/// A deserialization error produced when trying to deserialize json
/// as a particular return value type.
UnsupportedReturnValue(RBox<Unsupported>),
/// An invalid plugin.
InvalidPlugin(WhichPlugin),
/// A custom error.
Custom(RBoxError),
/// A list of errors.
Many(RVec<Error>),
}
/// 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<CommandDescription>,
}
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{}