1use super::SolType;
2use crate::{
3 Result, Word,
4 abi::TokenSeq,
5 private::SolTypeValue,
6 sol_data::{self, ByteCount, SupportedFixedBytes},
7};
8use alloc::{string::String, vec::Vec};
9use alloy_primitives::{Address, Bytes, FixedBytes, Function, I256, U256, aliases::*};
10
11pub trait SolValue: SolTypeValue<Self::SolType> {
36 type SolType: SolType;
38
39 #[inline]
43 fn sol_name(&self) -> &'static str {
44 Self::SolType::SOL_NAME
45 }
46
47 #[inline]
51 fn tokenize(&self) -> <Self::SolType as SolType>::Token<'_> {
52 <Self as SolTypeValue<Self::SolType>>::stv_to_tokens(self)
53 }
54
55 #[inline]
59 fn detokenize(token: <Self::SolType as SolType>::Token<'_>) -> Self
60 where
61 Self: From<<Self::SolType as SolType>::RustType>,
62 {
63 Self::from(<Self::SolType as SolType>::detokenize(token))
64 }
65
66 #[inline]
70 fn abi_encoded_size(&self) -> usize {
71 <Self as SolTypeValue<Self::SolType>>::stv_abi_encoded_size(self)
72 }
73
74 #[inline]
79 fn eip712_data_word(&self) -> Word {
80 <Self as SolTypeValue<Self::SolType>>::stv_eip712_data_word(self)
81 }
82
83 #[inline]
87 fn abi_encode_packed_to(&self, out: &mut Vec<u8>) {
88 <Self as SolTypeValue<Self::SolType>>::stv_abi_encode_packed_to(self, out)
89 }
90
91 #[inline]
95 fn abi_encode_packed(&self) -> Vec<u8> {
96 let mut out = Vec::new();
97 <Self as SolTypeValue<Self::SolType>>::stv_abi_encode_packed_to(self, &mut out);
98 out
99 }
100
101 #[inline]
105 fn abi_encode(&self) -> Vec<u8> {
106 Self::SolType::abi_encode(self)
107 }
108
109 #[inline]
113 fn abi_encode_sequence(&self) -> Vec<u8>
114 where
115 for<'a> <Self::SolType as SolType>::Token<'a>: TokenSeq<'a>,
116 {
117 Self::SolType::abi_encode_sequence(self)
118 }
119
120 #[inline]
124 fn abi_encode_params(&self) -> Vec<u8>
125 where
126 for<'a> <Self::SolType as SolType>::Token<'a>: TokenSeq<'a>,
127 {
128 Self::SolType::abi_encode_params(self)
129 }
130
131 fn abi_decode(data: &[u8]) -> Result<Self>
135 where
136 Self: From<<Self::SolType as SolType>::RustType>,
137 {
138 Self::SolType::abi_decode(data).map(Self::from)
139 }
140
141 fn abi_decode_validate(data: &[u8]) -> Result<Self>
145 where
146 Self: From<<Self::SolType as SolType>::RustType>,
147 {
148 Self::SolType::abi_decode_validate(data).map(Self::from)
149 }
150
151 #[inline]
155 fn abi_decode_params<'de>(data: &'de [u8]) -> Result<Self>
156 where
157 Self: From<<Self::SolType as SolType>::RustType>,
158 <Self::SolType as SolType>::Token<'de>: TokenSeq<'de>,
159 {
160 Self::SolType::abi_decode_params(data).map(Self::from)
161 }
162
163 #[inline]
167 fn abi_decode_params_validate<'de>(data: &'de [u8]) -> Result<Self>
168 where
169 Self: From<<Self::SolType as SolType>::RustType>,
170 <Self::SolType as SolType>::Token<'de>: TokenSeq<'de>,
171 {
172 Self::SolType::abi_decode_params_validate(data).map(Self::from)
173 }
174
175 #[inline]
179 fn abi_decode_sequence<'de>(data: &'de [u8]) -> Result<Self>
180 where
181 Self: From<<Self::SolType as SolType>::RustType>,
182 <Self::SolType as SolType>::Token<'de>: TokenSeq<'de>,
183 {
184 Self::SolType::abi_decode_sequence(data).map(Self::from)
185 }
186
187 #[inline]
191 fn abi_decode_sequence_validate<'de>(data: &'de [u8]) -> Result<Self>
192 where
193 Self: From<<Self::SolType as SolType>::RustType>,
194 <Self::SolType as SolType>::Token<'de>: TokenSeq<'de>,
195 {
196 Self::SolType::abi_decode_sequence_validate(data).map(Self::from)
197 }
198}
199
200macro_rules! impl_sol_value {
201 ($($(#[$attr:meta])* [$($gen:tt)*] $rust:ty => $sol:ty [$($where:tt)*];)+) => {$(
202 $(#[$attr])*
203 impl<$($gen)*> SolValue for $rust $($where)* {
204 type SolType = $sol;
205 }
206 )*};
207}
208
209impl_sol_value! {
210 [] bool => sol_data::Bool [];
212
213 [] i8 => sol_data::Int::<8> [];
214 [] i16 => sol_data::Int::<16> [];
215 [] I24 => sol_data::Int::<24> [];
216 [] i32 => sol_data::Int::<32> [];
217 [] I40 => sol_data::Int::<40> [];
218 [] I48 => sol_data::Int::<48> [];
219 [] I56 => sol_data::Int::<56> [];
220 [] i64 => sol_data::Int::<64> [];
221 [] I72 => sol_data::Int::<72> [];
222 [] I80 => sol_data::Int::<80> [];
223 [] I88 => sol_data::Int::<88> [];
224 [] I96 => sol_data::Int::<96> [];
225 [] I104 => sol_data::Int::<104> [];
226 [] I112 => sol_data::Int::<112> [];
227 [] I120 => sol_data::Int::<120> [];
228 [] i128 => sol_data::Int::<128> [];
229 [] I136 => sol_data::Int::<136> [];
230 [] I144 => sol_data::Int::<144> [];
231 [] I152 => sol_data::Int::<152> [];
232 [] I160 => sol_data::Int::<160> [];
233 [] I168 => sol_data::Int::<168> [];
234 [] I176 => sol_data::Int::<176> [];
235 [] I184 => sol_data::Int::<184> [];
236 [] I192 => sol_data::Int::<192> [];
237 [] I200 => sol_data::Int::<200> [];
238 [] I208 => sol_data::Int::<208> [];
239 [] I216 => sol_data::Int::<216> [];
240 [] I224 => sol_data::Int::<224> [];
241 [] I232 => sol_data::Int::<232> [];
242 [] I240 => sol_data::Int::<240> [];
243 [] I248 => sol_data::Int::<248> [];
244 [] I256 => sol_data::Int::<256> [];
245
246 [] u16 => sol_data::Uint::<16> [];
249 [] U24 => sol_data::Uint::<24> [];
250 [] u32 => sol_data::Uint::<32> [];
251 [] U40 => sol_data::Uint::<40> [];
252 [] U48 => sol_data::Uint::<48> [];
253 [] U56 => sol_data::Uint::<56> [];
254 [] u64 => sol_data::Uint::<64> [];
255 [] U72 => sol_data::Uint::<72> [];
256 [] U80 => sol_data::Uint::<80> [];
257 [] U88 => sol_data::Uint::<88> [];
258 [] U96 => sol_data::Uint::<96> [];
259 [] U104 => sol_data::Uint::<104> [];
260 [] U112 => sol_data::Uint::<112> [];
261 [] U120 => sol_data::Uint::<120> [];
262 [] u128 => sol_data::Uint::<128> [];
263 [] U136 => sol_data::Uint::<136> [];
264 [] U144 => sol_data::Uint::<144> [];
265 [] U152 => sol_data::Uint::<152> [];
266 [] U160 => sol_data::Uint::<160> [];
267 [] U168 => sol_data::Uint::<168> [];
268 [] U176 => sol_data::Uint::<176> [];
269 [] U184 => sol_data::Uint::<184> [];
270 [] U192 => sol_data::Uint::<192> [];
271 [] U200 => sol_data::Uint::<200> [];
272 [] U208 => sol_data::Uint::<208> [];
273 [] U216 => sol_data::Uint::<216> [];
274 [] U224 => sol_data::Uint::<224> [];
275 [] U232 => sol_data::Uint::<232> [];
276 [] U240 => sol_data::Uint::<240> [];
277 [] U248 => sol_data::Uint::<248> [];
278 [] U256 => sol_data::Uint::<256> [];
279
280 [] Address => sol_data::Address [];
281 [] Function => sol_data::Function [];
282 [const N: usize] FixedBytes<N> => sol_data::FixedBytes<N> [where ByteCount<N>: SupportedFixedBytes];
283 [const N: usize] [u8; N] => sol_data::FixedBytes<N> [where ByteCount<N>: SupportedFixedBytes];
284
285 [T: SolValue] Vec<T> => sol_data::Array<T::SolType> [];
289 [T: SolValue] [T] => sol_data::Array<T::SolType> [];
290 [T: SolValue, const N: usize] [T; N] => sol_data::FixedArray<T::SolType, N> [];
291
292 ['a, T: ?Sized + SolValue] &'a T => T::SolType [where &'a T: SolTypeValue<T::SolType>];
293 ['a, T: ?Sized + SolValue] &'a mut T => T::SolType [where &'a mut T: SolTypeValue<T::SolType>];
294}
295
296macro_rules! tuple_impls {
297 ($count:literal $($ty:ident),+) => {
298 impl<$($ty: SolValue,)+> SolValue for ($($ty,)+) {
299 type SolType = ($($ty::SolType,)+);
300 }
301 };
302}
303
304impl SolValue for () {
305 type SolType = ();
306}
307
308all_the_tuples!(tuple_impls);
309
310impl SolValue for str {
312 type SolType = sol_data::String;
313
314 #[inline]
315 fn abi_encode(&self) -> Vec<u8> {
316 if self.is_empty() {
317 crate::abi::EMPTY_BYTES.to_vec()
318 } else {
319 <Self::SolType as SolType>::abi_encode(self)
320 }
321 }
322}
323
324impl SolValue for [u8] {
325 type SolType = sol_data::Bytes;
326
327 #[inline]
328 fn abi_encode(&self) -> Vec<u8> {
329 if self.is_empty() {
330 crate::abi::EMPTY_BYTES.to_vec()
331 } else {
332 <Self::SolType as SolType>::abi_encode(self)
333 }
334 }
335}
336
337impl SolValue for String {
338 type SolType = sol_data::String;
339
340 #[inline]
341 fn abi_encode(&self) -> Vec<u8> {
342 self[..].abi_encode()
343 }
344}
345
346impl SolValue for Bytes {
347 type SolType = sol_data::Bytes;
348
349 #[inline]
350 fn abi_encode(&self) -> Vec<u8> {
351 self[..].abi_encode()
352 }
353}
354
355impl SolValue for Vec<u8> {
356 type SolType = sol_data::Bytes;
357
358 #[inline]
359 fn abi_encode(&self) -> Vec<u8> {
360 self[..].abi_encode()
361 }
362}
363
364#[cfg(test)]
365#[allow(clippy::type_complexity)]
366mod tests {
367 use super::*;
368
369 #[allow(unused_imports)]
371 use crate::{SolType as _, private::SolTypeValue as _};
372
373 #[test]
374 fn inference() {
375 false.sol_name();
376 false.abi_encoded_size();
377 false.eip712_data_word();
378 false.abi_encode_packed_to(&mut vec![]);
379 false.abi_encode_packed();
380 false.abi_encode();
381 (false,).abi_encode_sequence();
382 (false,).abi_encode_params();
383
384 "".sol_name();
385 "".abi_encoded_size();
386 "".eip712_data_word();
387 "".abi_encode_packed_to(&mut vec![]);
388 "".abi_encode_packed();
389 "".abi_encode();
390 ("",).abi_encode_sequence();
391 ("",).abi_encode_params();
392
393 let _ = String::abi_decode(b"");
394 let _ = bool::abi_decode(b"");
395 }
396
397 #[test]
398 fn basic() {
399 assert_eq!(false.abi_encode(), Word::ZERO[..]);
400 assert_eq!(true.abi_encode(), Word::with_last_byte(1)[..]);
401
402 assert_eq!(0i8.abi_encode(), Word::ZERO[..]);
403 assert_eq!(0i16.abi_encode(), Word::ZERO[..]);
404 assert_eq!(0i32.abi_encode(), Word::ZERO[..]);
405 assert_eq!(0i64.abi_encode(), Word::ZERO[..]);
406 assert_eq!(0i128.abi_encode(), Word::ZERO[..]);
407 assert_eq!(I256::ZERO.abi_encode(), Word::ZERO[..]);
408
409 assert_eq!(0u16.abi_encode(), Word::ZERO[..]);
410 assert_eq!(0u32.abi_encode(), Word::ZERO[..]);
411 assert_eq!(0u64.abi_encode(), Word::ZERO[..]);
412 assert_eq!(0u128.abi_encode(), Word::ZERO[..]);
413 assert_eq!(U256::ZERO.abi_encode(), Word::ZERO[..]);
414
415 assert_eq!(Address::ZERO.abi_encode(), Word::ZERO[..]);
416 assert_eq!(Function::ZERO.abi_encode(), Word::ZERO[..]);
417
418 let encode_bytes = |b: &[u8]| {
419 let last = Word::new({
420 let mut buf = [0u8; 32];
421 buf[..b.len()].copy_from_slice(b);
422 buf
423 });
424 [
425 &Word::with_last_byte(0x20)[..],
426 &Word::with_last_byte(b.len() as u8)[..],
427 if b.is_empty() { b } else { &last[..] },
428 ]
429 .concat()
430 };
431
432 assert_eq!(b"".abi_encode(), encode_bytes(b""));
434 assert_eq!((b"" as &[_]).abi_encode(), encode_bytes(b""));
435 assert_eq!(b"a".abi_encode()[0], b'a');
437 assert_eq!(b"a".abi_encode()[1..], Word::ZERO[1..]);
438 assert_eq!((b"a" as &[_]).abi_encode(), encode_bytes(b"a"));
440
441 assert_eq!("".abi_encode(), encode_bytes(b""));
442 assert_eq!("a".abi_encode(), encode_bytes(b"a"));
443 assert_eq!(String::new().abi_encode(), encode_bytes(b""));
444 assert_eq!(String::from("a").abi_encode(), encode_bytes(b"a"));
445 assert_eq!(Vec::<u8>::new().abi_encode(), encode_bytes(b""));
446 assert_eq!(Vec::<u8>::from(&b"a"[..]).abi_encode(), encode_bytes(b"a"));
447 }
448
449 #[test]
450 fn big() {
451 let tuple = (
452 false,
453 0i8,
454 0i16,
455 0i32,
456 0i64,
457 0i128,
458 I256::ZERO,
459 0u16,
461 0u32,
462 0u64,
463 0u128,
464 U256::ZERO,
465 Address::ZERO,
466 Function::ZERO,
467 );
468 let encoded = tuple.abi_encode();
469 assert_eq!(encoded.len(), 32 * 14);
470 assert!(encoded.iter().all(|&b| b == 0));
471 }
472
473 #[test]
474 fn complex() {
475 let tuple = ((((((false,),),),),),);
476 assert_eq!(tuple.abi_encode(), Word::ZERO[..]);
477 assert_eq!(tuple.sol_name(), "((((((bool))))))");
478
479 let tuple = (
480 42u64,
481 "hello world",
482 true,
483 (
484 String::from("aaaa"),
485 Address::with_last_byte(69),
486 b"bbbb".to_vec(),
487 b"cccc",
488 &b"dddd"[..],
489 ),
490 );
491 assert_eq!(tuple.sol_name(), "(uint64,string,bool,(string,address,bytes,bytes4,bytes))");
492 }
493
494 #[test]
495 fn derefs() {
496 let x: &[Address; 0] = &[];
497 x.abi_encode();
498 assert_eq!(x.sol_name(), "address[0]");
499
500 let x = &[Address::ZERO];
501 x.abi_encode();
502 assert_eq!(x.sol_name(), "address[1]");
503
504 let x = &[Address::ZERO, Address::ZERO];
505 x.abi_encode();
506 assert_eq!(x.sol_name(), "address[2]");
507
508 let x = &[Address::ZERO][..];
509 x.abi_encode();
510 assert_eq!(x.sol_name(), "address[]");
511
512 let mut x = *b"0";
513 let x = (&mut x, *b"aaaa", b"00");
514 x.abi_encode();
515 assert_eq!(x.sol_name(), "(bytes1,bytes4,bytes2)");
516
517 let tuple = &(&0u16, &"", b"0", &mut [Address::ZERO][..]);
518 tuple.abi_encode();
519 assert_eq!(tuple.sol_name(), "(uint16,string,bytes1,address[])");
520 }
521
522 #[test]
523 fn decode() {
524 let _: Result<String> = String::abi_decode(b"");
525
526 let _: Result<Vec<String>> = Vec::<String>::abi_decode(b"");
527
528 let _: Result<(u64, String, U256)> = <(u64, String, U256)>::abi_decode(b"");
529 let _: Result<(i64, Vec<(u32, String, Vec<FixedBytes<4>>)>, U256)> =
530 <(i64, Vec<(u32, String, Vec<FixedBytes<4>>)>, U256)>::abi_decode(b"");
531 }
532
533 #[test]
534 fn empty_spec() {
535 assert_eq!("".abi_encode(), crate::abi::EMPTY_BYTES);
536 assert_eq!(b"".abi_encode(), crate::abi::EMPTY_BYTES);
537 assert_eq!(
538 ("", "a").abi_encode(),
539 <(sol_data::String, sol_data::String)>::abi_encode(&("", "a"))
540 );
541 assert_eq!(
542 ("a", "").abi_encode(),
543 <(sol_data::String, sol_data::String)>::abi_encode(&("a", ""))
544 );
545 assert_eq!(
546 (&b""[..], &b"a"[..]).abi_encode(),
547 <(sol_data::Bytes, sol_data::Bytes)>::abi_encode(&(b"", b"a"))
548 );
549 assert_eq!(
550 (&b"a"[..], &b""[..]).abi_encode(),
551 <(sol_data::Bytes, sol_data::Bytes)>::abi_encode(&(b"a", b""))
552 );
553 }
554}