use core::any::Any;
use casper_types::bytesrepr::Error as BytesReprError;
use casper_types::{CLType, CLValueError};
use crate::arithmetic::ArithmeticsError;
use crate::prelude::*;
use crate::VmError::Serialization;
#[repr(u16)]
#[derive(Clone, Debug, PartialEq)]
pub enum OdraError {
ExecutionError(ExecutionError),
VmError(VmError)
}
impl OdraError {
pub fn code(&self) -> u16 {
match self {
OdraError::ExecutionError(e) => e.code(),
OdraError::VmError(_e) => 0
}
}
pub fn user(code: u16) -> Self {
if code >= ExecutionError::UserErrorTooHigh.code() {
ExecutionError::UserErrorTooHigh.into()
} else {
ExecutionError::User(code).into()
}
}
}
impl From<ArithmeticsError> for ExecutionError {
fn from(error: ArithmeticsError) -> Self {
match error {
ArithmeticsError::AdditionOverflow => Self::AdditionOverflow,
ArithmeticsError::SubtractingOverflow => Self::SubtractionOverflow
}
}
}
impl From<ArithmeticsError> for OdraError {
fn from(error: ArithmeticsError) -> Self {
Into::<ExecutionError>::into(error).into()
}
}
impl From<Box<dyn Any + Send>> for OdraError {
fn from(_: Box<dyn Any + Send>) -> Self {
OdraError::VmError(VmError::Panic)
}
}
impl From<casper_types::bytesrepr::Error> for ExecutionError {
fn from(error: casper_types::bytesrepr::Error) -> Self {
match error {
casper_types::bytesrepr::Error::EarlyEndOfStream => Self::EarlyEndOfStream,
casper_types::bytesrepr::Error::Formatting => Self::Formatting,
casper_types::bytesrepr::Error::LeftOverBytes => Self::LeftOverBytes,
casper_types::bytesrepr::Error::OutOfMemory => Self::OutOfMemory,
casper_types::bytesrepr::Error::NotRepresentable => Self::NotRepresentable,
casper_types::bytesrepr::Error::ExceededRecursionDepth => Self::ExceededRecursionDepth,
_ => Self::Formatting
}
}
}
#[repr(u16)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ExecutionError {
UnwrapError = 1,
UnexpectedError = 2,
AdditionOverflow = 100,
SubtractionOverflow = 101,
NonPayable = 102,
TransferToContract = 103,
ReentrantCall = 104,
ContractAlreadyInstalled = 105,
UnknownConstructor = 106,
NativeTransferError = 107,
IndexOutOfBounds = 108,
ZeroAddress = 109,
AddressCreationFailed = 110,
EarlyEndOfStream = 111,
Formatting = 112,
LeftOverBytes = 113,
OutOfMemory = 114,
NotRepresentable = 115,
ExceededRecursionDepth = 116,
KeyNotFound = 117,
CouldNotDeserializeSignature = 118,
TypeMismatch = 119,
CouldNotSignMessage = 120,
EmptyDictionaryName = 121,
MissingArg = 122,
MissingAddress = 123,
OutOfGas = 124,
MaxUserError = 64535,
UserErrorTooHigh = 64536,
User(u16)
}
impl ExecutionError {
pub fn code(&self) -> u16 {
unsafe {
match self {
ExecutionError::User(code) => *code,
ExecutionError::MaxUserError => 64535,
ExecutionError::UserErrorTooHigh => 64536,
_ => ExecutionError::UserErrorTooHigh.code() + *(self as *const Self as *const u16)
}
}
}
}
impl From<ExecutionError> for OdraError {
fn from(error: ExecutionError) -> Self {
Self::ExecutionError(error)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum VmError {
Serialization,
Deserialization,
BalanceExceeded,
NoSuchMethod(String),
InvalidContractAddress,
InvalidContext,
TypeMismatch {
expected: CLType,
found: CLType
},
Other(String),
Panic
}
pub enum CollectionError {
IndexOutOfBounds
}
impl From<CollectionError> for ExecutionError {
fn from(error: CollectionError) -> Self {
match error {
CollectionError::IndexOutOfBounds => Self::IndexOutOfBounds
}
}
}
impl From<CollectionError> for OdraError {
fn from(error: CollectionError) -> Self {
Into::<ExecutionError>::into(error).into()
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum AddressError {
ZeroAddress,
AddressCreationError
}
impl From<AddressError> for ExecutionError {
fn from(error: AddressError) -> Self {
match error {
AddressError::ZeroAddress => Self::ZeroAddress,
AddressError::AddressCreationError => Self::AddressCreationFailed
}
}
}
impl From<AddressError> for OdraError {
fn from(error: AddressError) -> Self {
Into::<ExecutionError>::into(error).into()
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd)]
pub enum EventError {
UnexpectedType(String),
IndexOutOfBounds,
Formatting,
Parsing,
CouldntExtractName,
CouldntExtractEventData
}
pub type OdraResult<T> = Result<T, OdraError>;
impl From<CLValueError> for OdraError {
fn from(error: CLValueError) -> Self {
match error {
CLValueError::Serialization(_) => OdraError::VmError(Serialization),
CLValueError::Type(cl_type_mismatch) => OdraError::VmError(VmError::TypeMismatch {
expected: cl_type_mismatch.expected.clone(),
found: cl_type_mismatch.found.clone()
})
}
}
}
impl From<BytesReprError> for OdraError {
fn from(error: BytesReprError) -> Self {
match error {
BytesReprError::EarlyEndOfStream => ExecutionError::EarlyEndOfStream,
BytesReprError::Formatting => ExecutionError::Formatting,
BytesReprError::LeftOverBytes => ExecutionError::LeftOverBytes,
BytesReprError::OutOfMemory => ExecutionError::OutOfMemory,
BytesReprError::NotRepresentable => ExecutionError::NotRepresentable,
BytesReprError::ExceededRecursionDepth => ExecutionError::ExceededRecursionDepth,
_ => ExecutionError::Formatting
}
.into()
}
}