ink_primitives/sol/
params.rs1use alloy_sol_types::{
16 SolType as AlloySolType,
17 abi,
18};
19use impl_trait_for_tuples::impl_for_tuples;
20use ink_prelude::vec::Vec;
21
22use super::{
23 Error,
24 SolDecode,
25 SolEncode,
26 SolTypeDecode,
27 SolTypeEncode,
28 encodable::{
29 Encodable,
30 EncodableParams,
31 },
32 encoder::Encoder,
33 types::SolTokenType,
34};
35
36pub trait SolParamsDecode: SolDecode + Sized + private::Sealed {
42 const SOL_NAME: &'static str = <Self as SolDecode>::SOL_NAME;
44
45 fn decode(data: &[u8]) -> Result<Self, Error>;
47}
48
49pub trait SolParamsEncode<'a>: SolEncode<'a> + private::Sealed {
56 const SOL_NAME: &'static str = <Self as SolEncode<'a>>::SOL_NAME;
58
59 fn encode(&'a self) -> Vec<u8>;
61
62 fn encode_to(&'a self, buffer: &mut [u8]) -> usize;
65}
66
67#[impl_for_tuples(1, 12)]
71#[tuple_types_custom_trait_bound(SolDecode)]
72impl SolParamsDecode for Tuple {
73 fn decode(data: &[u8]) -> Result<Self, Error> {
74 abi::decode_params::<
75 <<<Self as SolDecode>::SolType as SolTypeDecode>::AlloyType as AlloySolType>::Token<'_>,
76 >(data)
77 .map_err(Error::from)
78 .and_then(<<Self as SolDecode>::SolType as SolTypeDecode>::detokenize)
79 .and_then(<Self as SolDecode>::from_sol_type)
80 }
81}
82
83#[impl_for_tuples(1, 12)]
84#[tuple_types_custom_trait_bound(SolEncode<'a>)]
85impl<'a> SolParamsEncode<'a> for Tuple {
86 fn encode(&'a self) -> Vec<u8> {
87 let params = self.to_sol_type();
88 let token = <<Self as SolEncode>::SolType as SolTypeEncode>::tokenize(¶ms);
89 let encoded_size = if <<<Self as SolEncode>::SolType as SolTokenType>::TokenType<
92 'a,
93 > as Encodable>::DYNAMIC
94 {
95 token.tail_words()
96 } else {
97 token.head_words()
98 }
99 .checked_mul(32)
100 .unwrap();
101 let mut buffer = ink_prelude::vec![0u8; encoded_size];
102 let mut encoder = Encoder::new(buffer.as_mut_slice());
103 EncodableParams::encode_params(&token, &mut encoder);
104 buffer
105 }
106
107 fn encode_to(&'a self, buffer: &mut [u8]) -> usize {
108 let params = self.to_sol_type();
109 let token = <<Self as SolEncode>::SolType as SolTypeEncode>::tokenize(¶ms);
110 let mut encoder = Encoder::new(buffer);
111 EncodableParams::encode_params(&token, &mut encoder);
112 let encoded_words = if <<<Self as SolEncode>::SolType as SolTokenType>::TokenType<
115 'a,
116 > as Encodable>::DYNAMIC
117 {
118 token.tail_words()
119 } else {
120 token.head_words()
121 };
122 encoded_words.checked_mul(32).unwrap()
123 }
124}
125
126impl SolParamsDecode for () {
128 fn decode(_: &[u8]) -> Result<Self, Error> {
129 Ok(())
131 }
132}
133
134impl SolParamsEncode<'_> for () {
135 fn encode(&self) -> Vec<u8> {
136 Vec::new()
137 }
138
139 fn encode_to(&self, _: &mut [u8]) -> usize {
140 0
141 }
142}
143
144#[impl_for_tuples(12)]
145#[tuple_types_no_default_trait_bound]
146impl private::Sealed for Tuple {}
147
148mod private {
149 pub trait Sealed {}
151}