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