1use alloc::vec::Vec;
7use gear_core_errors::ReplyCode;
8use gprimitives::H256;
9use parity_scale_codec::{Decode, Encode};
10use scale_decode::DecodeAsType;
11use scale_encode::EncodeAsType;
12use scale_info::TypeInfo;
13
14use crate::message::UserMessage;
15
16#[derive(
20 Clone, Debug, Default, PartialEq, Eq, Encode, EncodeAsType, Decode, DecodeAsType, TypeInfo,
21)]
22#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
23pub struct GasInfo {
24 pub min_limit: u64,
26 pub reserved: u64,
28 pub burned: u64,
30 pub may_be_returned: u64,
32 pub waited: bool,
36}
37
38#[derive(
42 Clone, Debug, PartialEq, Eq, Encode, EncodeAsType, Decode, DecodeAsType, TypeInfo, Hash,
43)]
44#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
45pub struct ReplyInfo {
46 #[cfg_attr(feature = "std", serde(with = "impl_serde::serialize"))]
48 pub payload: Vec<u8>,
49 pub value: u128,
51 #[cfg_attr(feature = "std", serde(with = "serialize_reply_code"))]
53 pub code: ReplyCode,
54}
55
56#[derive(
58 Clone, Debug, PartialEq, Eq, Encode, EncodeAsType, Decode, DecodeAsType, TypeInfo, Hash,
59)]
60#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
61pub struct CalculateReplyForHandleResult {
62 pub reply: ReplyInfo,
64 pub messages: Vec<UserMessage>,
66}
67
68impl ReplyInfo {
69 pub fn to_hash(&self) -> H256 {
71 let ReplyInfo {
72 payload,
73 value,
74 code,
75 } = self;
76
77 let bytes = [
78 payload.as_ref(),
79 value.to_be_bytes().as_ref(),
80 code.to_bytes().as_ref(),
81 ]
82 .concat();
83 super::utils::hash(&bytes).into()
84 }
85}
86
87#[cfg(feature = "std")]
89pub(crate) mod serialize_reply_code {
90 use super::ReplyCode;
91 use core::fmt::Write;
92 use serde::de;
93
94 pub fn serialize<S>(code: &ReplyCode, serializer: S) -> Result<S::Ok, S::Error>
95 where
96 S: serde::Serializer,
97 {
98 let mut s = alloc::string::String::with_capacity(10);
99 s.push_str("0x");
100 for byte in code.to_bytes() {
101 write!(&mut s, "{:02x}", byte).unwrap();
102 }
103 serializer.serialize_str(&s)
104 }
105
106 pub fn deserialize<'de, D>(deserializer: D) -> Result<ReplyCode, D::Error>
107 where
108 D: serde::Deserializer<'de>,
109 {
110 struct Visitor;
111
112 impl<'b> de::Visitor<'b> for Visitor {
113 type Value = ReplyCode;
114
115 fn expecting(&self, formatter: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
116 formatter.write_str("a 0x-prefixed hex string representing a 4-byte ReplyCode")
117 }
118
119 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
120 where
121 E: de::Error,
122 {
123 let v = v.strip_prefix("0x").ok_or_else(|| {
124 E::custom("invalid format: expected a 0x-prefixed hex string")
125 })?;
126 let mut bytes = [0u8; 4];
127 hex::decode_to_slice(v, &mut bytes)
128 .map_err(|e| E::custom(alloc::format!("invalid hex string: {e}")))?;
129 Ok(ReplyCode::from_bytes(bytes))
130 }
131 }
132 deserializer.deserialize_str(Visitor)
133 }
134}
135
136#[derive(
138 Clone,
139 Copy,
140 Debug,
141 Default,
142 PartialEq,
143 Eq,
144 Encode,
145 EncodeAsType,
146 Decode,
147 DecodeAsType,
148 TypeInfo,
149 derive_more::From,
150 derive_more::Into,
151)]
152pub struct RpcValue(pub u128);
153
154#[cfg(feature = "std")]
155impl<'de> serde::Deserialize<'de> for RpcValue {
156 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
157 where
158 D: serde::Deserializer<'de>,
159 {
160 use alloc::format;
161 use core::fmt;
162 use serde::de::{self, Visitor};
163
164 struct RpcValueVisitor;
165
166 impl<'de> Visitor<'de> for RpcValueVisitor {
167 type Value = RpcValue;
168
169 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
170 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")
171 }
172
173 fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E> {
174 Ok(RpcValue(v))
175 }
176
177 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> {
178 Ok(RpcValue(v as u128))
179 }
180
181 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
182 where
183 E: de::Error,
184 {
185 if let Some(hex) = v.strip_prefix("0x") {
186 let bytes = hex::decode(hex)
187 .map_err(|e| E::custom(format!("invalid hex string: {e}")))?;
188
189 if bytes.len() > 16 {
190 return Err(E::custom("invalid hex string: too long for u128"));
191 }
192
193 let mut padded = [0u8; 16];
195 padded[16 - bytes.len()..].copy_from_slice(&bytes);
196
197 Ok(RpcValue(u128::from_be_bytes(padded)))
198 } else {
199 v.parse::<u128>()
200 .map(RpcValue)
201 .map_err(|e| E::custom(format!("invalid numeric string: {e}")))
202 }
203 }
204 }
205
206 deserializer.deserialize_any(RpcValueVisitor)
207 }
208}