1use fuel_types::{Address, AssetId, ContractId};
2
3use crate::types::{
4 param_types::{EnumVariants, ParamType},
5 AsciiString, Bits256, Bytes, RawSlice, SizedAsciiString,
6};
7
8pub trait Parameterize {
11 fn param_type() -> ParamType;
12}
13
14impl Parameterize for Bits256 {
15 fn param_type() -> ParamType {
16 ParamType::B256
17 }
18}
19
20impl Parameterize for RawSlice {
21 fn param_type() -> ParamType {
22 ParamType::RawSlice
23 }
24}
25
26impl<const SIZE: usize, T: Parameterize> Parameterize for [T; SIZE] {
27 fn param_type() -> ParamType {
28 ParamType::Array(Box::new(T::param_type()), SIZE)
29 }
30}
31
32impl<T: Parameterize> Parameterize for Vec<T> {
33 fn param_type() -> ParamType {
34 ParamType::Vector(Box::new(T::param_type()))
35 }
36}
37
38impl Parameterize for Bytes {
39 fn param_type() -> ParamType {
40 ParamType::Bytes
41 }
42}
43
44impl Parameterize for String {
45 fn param_type() -> ParamType {
46 ParamType::String
47 }
48}
49
50impl Parameterize for Address {
51 fn param_type() -> ParamType {
52 ParamType::Struct {
53 name: "Address".to_string(),
54 fields: vec![("0".to_string(), ParamType::B256)],
55 generics: vec![],
56 }
57 }
58}
59
60impl Parameterize for ContractId {
61 fn param_type() -> ParamType {
62 ParamType::Struct {
63 name: "ContractId".to_string(),
64 fields: vec![("0".to_string(), ParamType::B256)],
65 generics: vec![],
66 }
67 }
68}
69
70impl Parameterize for AssetId {
71 fn param_type() -> ParamType {
72 ParamType::Struct {
73 name: "AssetId".to_string(),
74 fields: vec![("0".to_string(), ParamType::B256)],
75 generics: vec![],
76 }
77 }
78}
79
80impl Parameterize for () {
81 fn param_type() -> ParamType {
82 ParamType::Unit
83 }
84}
85
86impl Parameterize for bool {
87 fn param_type() -> ParamType {
88 ParamType::Bool
89 }
90}
91
92impl Parameterize for u8 {
93 fn param_type() -> ParamType {
94 ParamType::U8
95 }
96}
97
98impl Parameterize for u16 {
99 fn param_type() -> ParamType {
100 ParamType::U16
101 }
102}
103
104impl Parameterize for u32 {
105 fn param_type() -> ParamType {
106 ParamType::U32
107 }
108}
109
110impl Parameterize for u64 {
111 fn param_type() -> ParamType {
112 ParamType::U64
113 }
114}
115
116impl Parameterize for u128 {
117 fn param_type() -> ParamType {
118 ParamType::U128
119 }
120}
121
122impl<T> Parameterize for Option<T>
123where
124 T: Parameterize,
125{
126 fn param_type() -> ParamType {
127 let variant_param_types = vec![
128 ("None".to_string(), ParamType::Unit),
129 ("Some".to_string(), T::param_type()),
130 ];
131 let enum_variants = EnumVariants::new(variant_param_types)
132 .expect("should never happen as we provided valid Option param types");
133 ParamType::Enum {
134 name: "Option".to_string(),
135 enum_variants,
136 generics: vec![T::param_type()],
137 }
138 }
139}
140
141impl<T, E> Parameterize for Result<T, E>
142where
143 T: Parameterize,
144 E: Parameterize,
145{
146 fn param_type() -> ParamType {
147 let variant_param_types = vec![
148 ("Ok".to_string(), T::param_type()),
149 ("Err".to_string(), E::param_type()),
150 ];
151 let enum_variants = EnumVariants::new(variant_param_types)
152 .expect("should never happen as we provided valid Result param types");
153 ParamType::Enum {
154 name: "Result".to_string(),
155 enum_variants,
156 generics: vec![T::param_type(), E::param_type()],
157 }
158 }
159}
160
161impl<const LEN: usize> Parameterize for SizedAsciiString<LEN> {
162 fn param_type() -> ParamType {
163 ParamType::StringArray(LEN)
164 }
165}
166
167impl Parameterize for AsciiString {
168 fn param_type() -> ParamType {
169 ParamType::StringSlice
170 }
171}
172
173macro_rules! impl_parameterize_tuples {
178 ($num: expr, $( $ty: ident : $no: tt, )+) => {
179 impl<$($ty, )+> Parameterize for ($($ty,)+) where
180 $(
181 $ty: Parameterize,
182 )+
183 {
184 fn param_type() -> ParamType {
185 ParamType::Tuple(vec![
186 $( $ty::param_type(), )+
187 ])
188 }
189
190 }
191 }
192}
193
194impl_parameterize_tuples!(1, A:0, );
197impl_parameterize_tuples!(2, A:0, B:1, );
198impl_parameterize_tuples!(3, A:0, B:1, C:2, );
199impl_parameterize_tuples!(4, A:0, B:1, C:2, D:3, );
200impl_parameterize_tuples!(5, A:0, B:1, C:2, D:3, E:4, );
201impl_parameterize_tuples!(6, A:0, B:1, C:2, D:3, E:4, F:5, );
202impl_parameterize_tuples!(7, A:0, B:1, C:2, D:3, E:4, F:5, G:6, );
203impl_parameterize_tuples!(8, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, );
204impl_parameterize_tuples!(9, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, );
205impl_parameterize_tuples!(10, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, );
206impl_parameterize_tuples!(11, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, );
207impl_parameterize_tuples!(12, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, );
208impl_parameterize_tuples!(13, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, );
209impl_parameterize_tuples!(14, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, );
210impl_parameterize_tuples!(15, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, );
211impl_parameterize_tuples!(16, A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, );
212
213#[cfg(test)]
214mod tests {
215 use super::*;
216
217 #[test]
218 fn sized_ascii_string_is_parameterized_correctly() {
219 let param_type = SizedAsciiString::<3>::param_type();
220
221 assert!(matches!(param_type, ParamType::StringArray(3)));
222 }
223
224 #[test]
225 fn test_param_type_b256() {
226 assert_eq!(Bits256::param_type(), ParamType::B256);
227 }
228
229 #[test]
230 fn test_param_type_raw_slice() {
231 assert_eq!(RawSlice::param_type(), ParamType::RawSlice);
232 }
233}