tsdk: Clean up errors. - wasm-runtime - A wasm runtime
 (HTM) git clone https://git.parazyd.org/wasm-runtime
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit 5f8ad66aa984f882f4c2d8926c9e15e26f6d5825
 (DIR) parent e4fae9954d20225831248af32972253a3577d25f
 (HTM) Author: parazyd <parazyd@dyne.org>
       Date:   Tue,  8 Mar 2022 23:32:59 +0100
       
       sdk: Clean up errors.
       
       Diffstat:
         M drk-sdk/Cargo.toml                  |       1 +
         M drk-sdk/src/error.rs                |      59 ++++++++++++++++++++-----------
       
       2 files changed, 39 insertions(+), 21 deletions(-)
       ---
 (DIR) diff --git a/drk-sdk/Cargo.toml b/drk-sdk/Cargo.toml
       t@@ -4,4 +4,5 @@ version = "0.1.0"
        edition = "2021"
        
        [dependencies]
       +borsh = "0.9.3"
        thiserror = "1.0.30"
 (DIR) diff --git a/drk-sdk/src/error.rs b/drk-sdk/src/error.rs
       t@@ -1,51 +1,68 @@
       +use borsh::maybestd::io::Error as BorshIoError;
        use std::result::Result as ResultGeneric;
        
        pub type ContractResult = ResultGeneric<(), ContractError>;
        
        #[derive(Debug, thiserror::Error)]
       -#[repr(C)]
        pub enum ContractError {
       +    /// Allows on-chain programs to implement contract-specific error types and
       +    /// see them returned by the runtime. A contract-specific error may be any
       +    /// type that is represented as or serialized to an u32 inteter.
       +    #[error("Custom contract error: {0:#x}")]
       +    Custom(u32),
       +
            #[error("Internal error")]
            Internal,
       -
            #[error("Out of memory")]
            OutOfMemory,
       +    #[error("IO error: {0}")]
       +    BorshIoError(String),
       +}
        
       -    #[error("IO error")]
       -    Io,
       -
       -    #[error("Custom contract error: {0:#x}")]
       -    Custom(u32),
       +/// Builtin return values occupy the upper 32 bits
       +const BUILTIN_BIT_SHIFT: usize = 32;
       +macro_rules! to_builtin {
       +    ($error:expr) => {
       +        ($error as u64) << BUILTIN_BIT_SHIFT
       +    };
        }
        
       -pub const INTERNAL_ERROR: u64 = 1;
       -pub const OUT_OF_MEMORY: u64 = 2;
       -pub const IO_ERROR: u64 = 3;
       +pub const CUSTOM_ZERO: u64 = to_builtin!(1);
       +pub const INTERNAL_ERROR: u64 = to_builtin!(2);
       +pub const OUT_OF_MEMORY: u64 = to_builtin!(3);
       +pub const BORSH_IO_ERROR: u64 = to_builtin!(4);
        
        impl From<ContractError> for u64 {
            fn from(err: ContractError) -> Self {
                match err {
                    ContractError::Internal => INTERNAL_ERROR,
                    ContractError::OutOfMemory => OUT_OF_MEMORY,
       -            ContractError::Io => IO_ERROR,
       -            ContractError::Custom(e) => e.into(),
       +            ContractError::BorshIoError(_) => BORSH_IO_ERROR,
       +            ContractError::Custom(error) => {
       +                if error == 0 {
       +                    CUSTOM_ZERO
       +                } else {
       +                    error as u64
       +                }
       +            }
                }
            }
        }
        
        impl From<u64> for ContractError {
       -    fn from(err: u64) -> Self {
       -        match err {
       -            INTERNAL_ERROR => ContractError::Internal,
       -            OUT_OF_MEMORY => ContractError::OutOfMemory,
       -            IO_ERROR => ContractError::Io,
       -            e => ContractError::Custom(e.try_into().unwrap()),
       +    fn from(error: u64) -> Self {
       +        match error {
       +            CUSTOM_ZERO => Self::Custom(0),
       +            INTERNAL_ERROR => Self::Internal,
       +            OUT_OF_MEMORY => Self::OutOfMemory,
       +            BORSH_IO_ERROR => Self::BorshIoError("Unknown".to_string()),
       +            _ => Self::Custom(error as u32),
                }
            }
        }
        
       -impl From<std::io::Error> for ContractError {
       -    fn from(_: std::io::Error) -> Self {
       -        Self::Io
       +impl From<BorshIoError> for ContractError {
       +    fn from(error: BorshIoError) -> Self {
       +        Self::BorshIoError(format!("{}", error))
            }
        }