gsdk 2.0.0

Rust SDK of the Gear network
Documentation
// Copyright (C) Gear Technologies Inc.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

//! GSdk Results

use std::borrow::Borrow;

pub use crate::tx_status::{TxError, TxStatusExt, TxSuccess};

use gear_core::{ids::ActorId, pages::GearPage};
use subxt::{
    error::DispatchError,
    ext::{scale_encode, subxt_rpcs},
};

/// Custom Result
pub type Result<T, E = Error> = std::result::Result<T, E>;

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("the queried event not found")]
    EventNotFound,

    #[error("the queried storage entry not found")]
    StorageEntryNotFound,

    #[error("subscription has been died")]
    SubscriptionDied,

    #[error("program has been terminated")]
    ProgramTerminated,

    #[error("funds overcame `u128::MAX`")]
    BalanceOverflow,

    #[error("incomplete batch result: expected {expected} values, found {found} values")]
    IncompleteBatchResult { expected: usize, found: usize },

    #[error("invalid secret phrase or key material")]
    InvalidSecret,

    #[error("{0} was not found in the storage")]
    PageNotFound(FailedPage),

    #[error("failed to migrate program `{}`: it already exists at the destination", .0)]
    ProgramAlreadyExists(ActorId),

    #[error(transparent)]
    FromUtf8(#[from] std::string::FromUtf8Error),

    #[error(transparent)]
    FromHex(#[from] hex::FromHexError),

    #[error(transparent)]
    PageError(#[from] gear_core::pages::PageError),

    #[error(transparent)]
    Io(#[from] std::io::Error),

    #[error(transparent)]
    SerdeJson(#[from] serde_json::Error),

    #[error(transparent)]
    Tx(#[from] TxError),

    #[error("failed to parse URL: {0}")]
    InvalidUrl(#[from] url::ParseError),

    #[error(transparent)]
    ClientError(#[from] jsonrpsee::core::ClientError),

    #[error(transparent)]
    Subxt(Box<subxt::Error>),

    #[error(transparent)]
    Codec(#[from] subxt::ext::codec::Error),

    #[error(transparent)]
    SubxtRpc(#[from] subxt_rpcs::Error),

    #[error(transparent)]
    SecretString(#[from] sp_core::crypto::SecretStringError),

    #[error(transparent)]
    ScaleEncode(#[from] scale_encode::Error),

    #[error(transparent)]
    Crypto(#[from] sp_core::crypto::PublicError),

    #[error(transparent)]
    Metadata(#[from] subxt::error::MetadataError),

    #[error("runtime error: {0:?}")]
    Runtime(crate::RuntimeError),
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, derive_more::Display)]
#[display("Page {} of Program {}", page, program)]
pub struct FailedPage {
    pub page: GearPage,
    pub program: ActorId,
}

impl FailedPage {
    pub fn new(page: GearPage, program: ActorId) -> Self {
        Self { page, program }
    }

    pub fn not_found(self) -> Error {
        Error::PageNotFound(self)
    }
}

impl From<crate::RuntimeError> for Error {
    fn from(error: crate::RuntimeError) -> Self {
        Self::Runtime(error)
    }
}

fn from_subxt_error<E: Borrow<subxt::Error> + Into<Box<subxt::Error>>>(error: E) -> Error {
    if let subxt::Error::Runtime(DispatchError::Module(err)) = error.borrow()
        && let Ok(runtime_error) = err.as_root_error()
    {
        Error::Runtime(runtime_error)
    } else {
        Error::Subxt(error.into())
    }
}

impl From<Box<subxt::Error>> for Error {
    fn from(error: Box<subxt::Error>) -> Self {
        from_subxt_error(error)
    }
}

impl From<subxt::Error> for Error {
    fn from(error: subxt::Error) -> Self {
        from_subxt_error(error)
    }
}