use alloc::vec::Vec;
use gear_core_errors::ReplyCode;
use parity_scale_codec::{Decode, Encode};
use scale_decode::DecodeAsType;
use scale_encode::EncodeAsType;
use scale_info::TypeInfo;
#[derive(
Clone, Debug, Default, PartialEq, Eq, Encode, EncodeAsType, Decode, DecodeAsType, TypeInfo,
)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub struct GasInfo {
pub min_limit: u64,
pub reserved: u64,
pub burned: u64,
pub may_be_returned: u64,
pub waited: bool,
}
#[derive(
Clone, Debug, PartialEq, Eq, Encode, EncodeAsType, Decode, DecodeAsType, TypeInfo, Hash,
)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub struct ReplyInfo {
#[cfg_attr(feature = "std", serde(with = "impl_serde::serialize"))]
pub payload: Vec<u8>,
pub value: u128,
pub code: ReplyCode,
}
#[derive(
Clone,
Copy,
Debug,
Default,
PartialEq,
Eq,
Encode,
EncodeAsType,
Decode,
DecodeAsType,
TypeInfo,
derive_more::From,
derive_more::Into,
)]
pub struct RpcValue(pub u128);
#[cfg(feature = "std")]
impl<'de> serde::Deserialize<'de> for RpcValue {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use alloc::format;
use core::fmt;
use serde::de::{self, Visitor};
struct RpcValueVisitor;
impl<'de> Visitor<'de> for RpcValueVisitor {
type Value = RpcValue;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("a numeric literal, a 0x-prefixed string with big-endian bytes, or a numeric string representing a u128; for large integer literals, consider using string options for clarity and to avoid potential parsing issues")
}
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E> {
Ok(RpcValue(v))
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> {
Ok(RpcValue(v as u128))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
if let Some(hex) = v.strip_prefix("0x") {
let bytes = hex::decode(hex)
.map_err(|e| E::custom(format!("invalid hex string: {e}")))?;
if bytes.len() > 16 {
return Err(E::custom("invalid hex string: too long for u128"));
}
let mut padded = [0u8; 16];
padded[16 - bytes.len()..].copy_from_slice(&bytes);
Ok(RpcValue(u128::from_be_bytes(padded)))
} else {
v.parse::<u128>()
.map(RpcValue)
.map_err(|e| E::custom(format!("invalid numeric string: {e}")))
}
}
}
deserializer.deserialize_any(RpcValueVisitor)
}
}