1use ink_prelude::vec::Vec;
18
19use crate::sol::{
20 SolDecode,
21 SolEncode,
22};
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
26pub enum Abi {
27 Ink,
29 Sol,
31}
32
33#[derive(Debug, Default, Clone, Copy)]
37pub struct Ink;
38
39#[derive(Debug, Default, Clone, Copy)]
43pub struct Sol;
44
45pub trait AbiEncodeWith<Abi> {
47 fn encode_with(&self) -> Vec<u8>;
49
50 fn encode_to_slice(&self, buffer: &mut [u8]) -> usize;
52
53 fn encode_to_vec(&self, buffer: &mut Vec<u8>);
55
56 fn encode_topic<H>(&self, hasher: H) -> [u8; 32]
64 where
65 H: Fn(&[u8], &mut [u8; 32]);
66}
67
68pub trait AbiDecodeWith<Abi>: Sized {
70 type Error: core::fmt::Debug;
72 fn decode_with(buffer: &[u8]) -> Result<Self, Self::Error>;
74}
75
76impl<T: scale::Encode> AbiEncodeWith<Ink> for T {
77 fn encode_with(&self) -> Vec<u8> {
78 scale::Encode::encode(self)
79 }
80
81 fn encode_to_slice(&self, buffer: &mut [u8]) -> usize {
82 let encoded = scale::Encode::encode(self);
83 let len = encoded.len();
84 debug_assert!(
85 len <= buffer.len(),
86 "encode scope buffer overflowed, encoded len is {} but buffer len is {}",
87 len,
88 buffer.len()
89 );
90 buffer[..len].copy_from_slice(&encoded);
91 len
92 }
93
94 fn encode_to_vec(&self, buffer: &mut Vec<u8>) {
95 scale::Encode::encode_to(self, buffer);
96 }
97
98 fn encode_topic<H>(&self, hasher: H) -> [u8; 32]
99 where
100 H: Fn(&[u8], &mut [u8; 32]),
101 {
102 let encoded = scale::Encode::encode(self);
103 let len = encoded.len();
104 let mut output = [0u8; 32];
105 if encoded.len() <= 32 {
106 output.as_mut()[0..len].copy_from_slice(&encoded);
107 } else {
108 hasher(&encoded, &mut output);
109 }
110 output
111 }
112}
113
114impl<T: scale::Decode> AbiDecodeWith<Ink> for T {
115 type Error = scale::Error;
116 fn decode_with(buffer: &[u8]) -> Result<Self, Self::Error> {
117 scale::Decode::decode(&mut &buffer[..])
118 }
119}
120
121impl<T> AbiEncodeWith<Sol> for T
122where
123 T: for<'a> SolEncode<'a>,
124{
125 fn encode_with(&self) -> Vec<u8> {
126 SolEncode::encode(self)
127 }
128
129 fn encode_to_slice(&self, buffer: &mut [u8]) -> usize {
130 let encoded = SolEncode::encode(self);
131 let len = encoded.len();
132 debug_assert!(
133 len <= buffer.len(),
134 "encode scope buffer overflowed, encoded len is {} but buffer len is {}",
135 len,
136 buffer.len()
137 );
138 buffer[..len].copy_from_slice(&encoded);
139 len
140 }
141
142 fn encode_to_vec(&self, buffer: &mut Vec<u8>) {
143 buffer.extend_from_slice(&T::encode(self));
144 }
145
146 fn encode_topic<H>(&self, hasher: H) -> [u8; 32]
147 where
148 H: Fn(&[u8], &mut [u8; 32]),
149 {
150 SolEncode::encode_topic(self, hasher)
151 }
152}
153
154impl<T: SolDecode> AbiDecodeWith<Sol> for T {
155 type Error = crate::sol::Error;
156 fn decode_with(buffer: &[u8]) -> Result<Self, Self::Error> {
157 T::decode(buffer)
158 }
159}