1use core::marker::PhantomData;
18
19use ink_primitives::{
20 abi::{
21 Ink,
22 Sol,
23 },
24 sol::{
25 SolErrorDecode,
26 SolResultDecode,
27 SolResultDecodeError,
28 },
29 LangError,
30 MessageResult,
31};
32use pallet_revive_uapi::ReturnErrorCode;
33use scale::{
34 Decode,
35 DecodeAll,
36};
37
38#[derive(Debug)]
42pub struct ReturnType<T>(PhantomData<fn() -> T>);
43
44impl<T> Clone for ReturnType<T> {
45 #[inline]
46 fn clone(&self) -> Self {
47 *self
48 }
49}
50
51impl<T> Copy for ReturnType<T> {}
52
53impl<T> Default for ReturnType<T> {
54 #[inline]
55 fn default() -> Self {
56 Self(Default::default())
57 }
58}
59
60#[derive(Debug, Copy, Clone)]
62pub struct Set<T>(pub T);
63
64impl<T> Set<T> {
65 #[inline]
67 pub fn value(self) -> T {
68 self.0
69 }
70}
71
72#[derive(Debug)]
74pub struct Unset<T>(PhantomData<fn() -> T>);
75
76impl<T> Clone for Unset<T> {
77 #[inline]
78 fn clone(&self) -> Self {
79 *self
80 }
81}
82
83impl<T> Copy for Unset<T> {}
84
85impl<T> Default for Unset<T> {
86 #[inline]
87 fn default() -> Self {
88 Self(Default::default())
89 }
90}
91
92pub trait Unwrap {
97 type Output;
99
100 fn unwrap_or_else<F>(self, f: F) -> Self::Output
102 where
103 F: FnOnce() -> Self::Output;
104}
105
106impl<T> Unwrap for Unset<T> {
107 type Output = T;
108
109 #[inline]
110 fn unwrap_or_else<F>(self, f: F) -> Self::Output
111 where
112 F: FnOnce() -> Self::Output,
113 {
114 f()
115 }
116}
117
118impl<T> Unwrap for Set<T> {
119 type Output = T;
120
121 #[inline]
122 fn unwrap_or_else<F>(self, _: F) -> Self::Output
123 where
124 F: FnOnce() -> Self::Output,
125 {
126 self.value()
127 }
128}
129
130pub trait DecodeMessageResult<Abi>: Sized {
138 fn decode_output(
141 buffer: &[u8],
142 did_revert: bool,
143 ) -> crate::Result<MessageResult<Self>>;
144}
145
146impl<R> DecodeMessageResult<Ink> for R
147where
148 R: Decode,
149 MessageResult<R>: Decode,
150{
151 fn decode_output(mut buffer: &[u8], _: bool) -> crate::Result<MessageResult<Self>> {
152 let decoded = MessageResult::<R>::decode_all(&mut buffer)?;
153 Ok(decoded)
154 }
155}
156
157impl<R> DecodeMessageResult<Sol> for R
158where
159 R: SolResultDecode,
160{
161 fn decode_output(
162 buffer: &[u8],
163 did_revert: bool,
164 ) -> crate::Result<MessageResult<Self>> {
165 let decoded = R::decode(buffer, did_revert)?;
168 Ok(Ok(decoded))
169 }
170}
171
172impl From<SolResultDecodeError> for crate::Error {
173 fn from(value: SolResultDecodeError) -> Self {
174 match value {
175 SolResultDecodeError::NonResultFromRevert => {
176 Self::ReturnError(ReturnErrorCode::CalleeReverted)
177 }
178 SolResultDecodeError::Decode => Self::DecodeSol(ink_primitives::sol::Error),
179 }
180 }
181}
182
183pub trait DecodeConstructorError<Abi>: Sized {
199 fn decode_error_output(buffer: &[u8]) -> ConstructorError<Self>;
201}
202
203pub enum ConstructorError<E> {
205 Contract(E),
207 Lang(LangError),
209 Env(crate::Error),
211}
212
213impl<E> DecodeConstructorError<Ink> for E
214where
215 E: Decode,
216{
217 fn decode_error_output(mut buffer: &[u8]) -> ConstructorError<Self> {
218 let out_return_value = &mut buffer;
223
224 const INVALID_OUTER_RESULT: &str = "Invalid outer constructor Result encoding, \
226 expected 0 or 1 as the first byte";
227 const INVALID_INNER_RESULT: &str = "Invalid inner constructor Result encoding, \
228 expected 0 or 1 as the first byte";
229 const REVERT_BUT_NOT_ERROR_DATA: &str =
230 "The callee reverted, but did not encode an error in the output buffer.";
231 fn scale_decode_err<T>(desc: &'static str) -> ConstructorError<T> {
232 ConstructorError::Env(crate::Error::Decode(desc.into()))
233 }
234
235 let Ok(lang_result_variant) = <_ as scale::Input>::read_byte(out_return_value)
236 else {
237 return scale_decode_err(INVALID_OUTER_RESULT);
238 };
239 match lang_result_variant {
240 0 => {
242 let Ok(inner_result_variant) =
243 <_ as scale::Input>::read_byte(out_return_value)
244 else {
245 return scale_decode_err(INVALID_INNER_RESULT);
246 };
247 match inner_result_variant {
248 0 => scale_decode_err(REVERT_BUT_NOT_ERROR_DATA),
250 1 => {
252 let decoded = <E as scale::Decode>::decode(out_return_value);
253 match decoded {
254 Ok(contract_err) => ConstructorError::Contract(contract_err),
255 Err(error) => {
256 ConstructorError::Env(crate::Error::Decode(error))
257 }
258 }
259 }
260 _ => scale_decode_err(INVALID_INNER_RESULT),
261 }
262 }
263 1 => {
265 let decoded = <LangError as scale::Decode>::decode(out_return_value);
266 match decoded {
267 Ok(lang_err) => ConstructorError::Lang(lang_err),
268 Err(error) => ConstructorError::Env(crate::Error::Decode(error)),
269 }
270 }
271 _ => scale_decode_err(INVALID_OUTER_RESULT),
272 }
273 }
274}
275
276impl<E> DecodeConstructorError<Sol> for E
277where
278 E: SolErrorDecode,
279{
280 fn decode_error_output(buffer: &[u8]) -> ConstructorError<Self> {
281 let decoded = SolErrorDecode::decode(buffer);
283 match decoded {
284 Ok(contract_err) => ConstructorError::Contract(contract_err),
285 Err(error) => ConstructorError::Env(crate::Error::DecodeSol(error)),
286 }
287 }
288}