ink_primitives/sol/error.rs
1// Copyright (C) ink! contributors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use ink_prelude::vec::Vec;
16
17use crate::sol::Error;
18
19/// Solidity ABI decode error data (if possible).
20pub trait SolErrorDecode {
21 /// Solidity ABI decode error data into this type.
22 fn decode(data: &[u8]) -> Result<Self, Error>
23 where
24 Self: Sized;
25}
26
27/// Solidity ABI encode as error data.
28pub trait SolErrorEncode {
29 /// Solidity ABI encode the value into Solidity error data.
30 fn encode(&self) -> Vec<u8>;
31}
32
33// Implements `SolErrorDecode` and `SolErrorEncode` for unit (i.e. `()`).
34// NOTE: While using unit as an error type is generally discouraged in idiomatic Rust,
35// it's the semantic representation of empty error data for Solidity ABI encoding.
36impl SolErrorDecode for () {
37 fn decode(data: &[u8]) -> Result<Self, Error>
38 where
39 Self: Sized,
40 {
41 if data.is_empty() {
42 Ok(())
43 } else {
44 Err(Error)
45 }
46 }
47}
48
49impl SolErrorEncode for () {
50 fn encode(&self) -> Vec<u8> {
51 Vec::new()
52 }
53}
54
55// Implements `SolErrorEncode` for reference types.
56macro_rules! impl_refs_error_encode {
57 ($($ty: ty),+ $(,)*) => {
58 $(
59 impl<T: SolErrorEncode> SolErrorEncode for $ty {
60 fn encode(&self) -> Vec<u8> {
61 T::encode(self)
62 }
63 }
64 )*
65 };
66}
67
68impl_refs_error_encode! {
69 &T, &mut T
70}