1use bobcat_maths::{I, U};
2
3use bobcat_storage::{Keccak256, keccak256_builder};
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7
8#[cfg(feature = "alloc")]
9use alloc::{string::String, vec::Vec};
10
11#[cfg(not(feature = "std"))]
12mod no_std {
13 #[cfg(feature = "alloc")]
14 use alloc::vec::Vec;
15
16 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
17 pub enum Error {
18 WriteAllEof,
19 ReadExactEof,
20 InvalidData,
21 }
22
23 pub trait Write {
24 fn write(&mut self, buf: &[u8]) -> Result<usize, Error>;
25 fn flush(&mut self) -> Result<(), Error>;
26 fn is_empty(&self) -> bool;
27
28 fn write_all(&mut self, mut buf: &[u8]) -> Result<(), Error> {
29 while !buf.is_empty() {
30 match self.write(buf) {
31 Ok(0) => return Err(Error::WriteAllEof),
32 Ok(n) if n <= buf.len() => buf = &buf[n..],
33 Ok(_) => return Err(Error::InvalidData),
34 Err(error) => return Err(error),
35 }
36 }
37 Ok(())
38 }
39 }
40
41 pub trait Read {
42 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error>;
43
44 fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<(), Error> {
45 while !buf.is_empty() {
46 match self.read(buf) {
47 Ok(0) => break,
48 Ok(n) if n <= buf.len() => buf = &mut buf[n..],
49 Ok(_) => return Err(Error::InvalidData),
50 Err(error) => return Err(error),
51 }
52 }
53 if buf.is_empty() {
54 Ok(())
55 } else {
56 Err(Error::ReadExactEof)
57 }
58 }
59 }
60
61 impl Write for &mut [u8] {
62 fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
63 let len = core::cmp::min(self.len(), buf.len());
64 let target = core::mem::take(self);
65 let (written, remaining) = target.split_at_mut(len);
66 written.copy_from_slice(&buf[..len]);
67 *self = remaining;
68 Ok(len)
69 }
70
71 fn flush(&mut self) -> Result<(), Error> {
72 Ok(())
73 }
74
75 fn is_empty(&self) -> bool {
76 <[u8]>::is_empty(self)
77 }
78 }
79
80 #[cfg(feature = "alloc")]
81 impl Write for Vec<u8> {
82 fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
83 self.extend_from_slice(buf);
84 Ok(buf.len())
85 }
86
87 fn flush(&mut self) -> Result<(), Error> {
88 Ok(())
89 }
90
91 fn is_empty(&self) -> bool {
92 Vec::is_empty(self)
93 }
94 }
95
96 #[cfg(feature = "alloc")]
97 impl Write for &mut Vec<u8> {
98 fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
99 (**self).write(buf)
100 }
101
102 fn flush(&mut self) -> Result<(), Error> {
103 (**self).flush()
104 }
105
106 fn is_empty(&self) -> bool {
107 Vec::is_empty(self)
108 }
109 }
110
111 impl Read for &[u8] {
112 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
113 let len = core::cmp::min(self.len(), buf.len());
114 buf[..len].copy_from_slice(&self[..len]);
115 *self = &self[len..];
116 Ok(len)
117 }
118 }
119
120 impl Read for &mut [u8] {
121 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
122 let len = core::cmp::min(self.len(), buf.len());
123 let source = core::mem::take(self);
124 let (read, remaining) = source.split_at_mut(len);
125 buf[..len].copy_from_slice(read);
126 *self = remaining;
127 Ok(len)
128 }
129 }
130}
131
132#[cfg(not(feature = "std"))]
133pub use no_std::{Error, Read, Write};
134
135#[cfg(feature = "std")]
136pub use std::io::{Error, Read, Write};
137
138#[doc(hidden)]
139#[derive(Clone)]
140pub struct SelectorHasher(Keccak256);
141
142impl SelectorHasher {
143 pub fn new() -> Self {
144 Self(keccak256_builder())
145 }
146
147 pub fn update(self, bytes: &[u8]) -> Self {
148 Self(self.0.update(bytes))
149 }
150
151 pub fn update_usize(self, mut value: usize) -> Self {
152 let mut digits = [0u8; 20];
153 let mut start = digits.len();
154 loop {
155 start -= 1;
156 digits[start] = b'0' + (value % 10) as u8;
157 value /= 10;
158 if value == 0 {
159 break;
160 }
161 }
162 self.update(&digits[start..])
163 }
164
165 pub fn selector(&self) -> [u8; 4] {
166 let hash = self.0.finalize();
167 [hash[0], hash[1], hash[2], hash[3]]
168 }
169}
170
171impl Default for SelectorHasher {
172 fn default() -> Self {
173 Self::new()
174 }
175}
176
177pub trait EvmCdWriteTarget {
178 type Writer<'a>: Write
179 where
180 Self: 'a;
181
182 fn writer(&mut self) -> Self::Writer<'_>;
183}
184
185impl EvmCdWriteTarget for [u8] {
186 type Writer<'a> = &'a mut [u8];
187
188 fn writer(&mut self) -> Self::Writer<'_> {
189 self
190 }
191}
192
193impl EvmCdWriteTarget for &mut [u8] {
194 type Writer<'a>
195 = &'a mut [u8]
196 where
197 Self: 'a;
198
199 fn writer(&mut self) -> Self::Writer<'_> {
200 self
201 }
202}
203
204impl<const N: usize> EvmCdWriteTarget for [u8; N] {
205 type Writer<'a> = &'a mut [u8];
206
207 fn writer(&mut self) -> Self::Writer<'_> {
208 self.as_mut_slice()
209 }
210}
211
212#[cfg(feature = "alloc")]
213impl EvmCdWriteTarget for Vec<u8> {
214 type Writer<'a> = &'a mut Vec<u8>;
215
216 fn writer(&mut self) -> Self::Writer<'_> {
217 self
218 }
219}
220
221pub trait EvmCdSerialise {
222 fn serialise<W: EvmCdWriteTarget + ?Sized>(&self, writer: &mut W) -> Result<(), Error> {
223 self.serialise_writer(&mut writer.writer())
224 }
225
226 fn serialise_to_array<const N: usize>(&self) -> Result<[u8; N], Error> {
227 let mut output = [0; N];
228 let mut writer = output.as_mut_slice();
229 self.serialise_writer(&mut writer)?;
230 if !writer.is_empty() {
231 return Err(invalid_data());
232 }
233 Ok(output)
234 }
235
236 #[cfg(feature = "alloc")]
237 fn serialise_to_vec(&self) -> Result<Vec<u8>, Error> {
238 let mut output = Vec::new();
239 self.serialise(&mut output)?;
240 Ok(output)
241 }
242
243 #[doc(hidden)]
244 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error>;
245
246 #[doc(hidden)]
247 fn serialise_value<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
248 self.serialise_writer(writer)
249 }
250
251 #[doc(hidden)]
252 fn is_abi_dynamic() -> bool {
253 false
254 }
255
256 #[doc(hidden)]
257 fn abi_head_size() -> usize {
258 32
259 }
260
261 #[doc(hidden)]
262 fn abi_tail_size(&self) -> usize {
263 0
264 }
265
266 #[doc(hidden)]
267 fn serialise_abi_head<W: Write>(
268 &self,
269 _tail_offset: usize,
270 writer: &mut W,
271 ) -> Result<(), Error> {
272 self.serialise_value(writer)
273 }
274
275 #[doc(hidden)]
276 fn serialise_abi_tail<W: Write>(&self, _writer: &mut W) -> Result<(), Error> {
277 Ok(())
278 }
279
280 #[doc(hidden)]
281 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher;
282}
283
284#[doc(hidden)]
285pub enum EvmCdHead<T> {
286 Value(T),
287 Offset(usize),
288}
289
290#[doc(hidden)]
291pub struct EvmCdStaticBufferKind;
292
293#[cfg(feature = "alloc")]
294#[doc(hidden)]
295pub struct EvmCdDynamicBufferKind;
296
297#[doc(hidden)]
298pub trait EvmCdBufferKind {
299 type Buffer<S>: EvmCdDecodeBuffer;
300 type Combined<Rhs: EvmCdBufferKind>: EvmCdBufferKind;
301}
302
303impl EvmCdBufferKind for EvmCdStaticBufferKind {
304 type Buffer<S> = EvmCdBuffer<S>;
305 type Combined<Rhs: EvmCdBufferKind> = Rhs;
306}
307
308#[cfg(feature = "alloc")]
309impl EvmCdBufferKind for EvmCdDynamicBufferKind {
310 type Buffer<S> = EvmCdDynamicBuffer<S>;
311 type Combined<Rhs: EvmCdBufferKind> = EvmCdDynamicBufferKind;
312}
313
314#[doc(hidden)]
315pub trait EvmCdDecodeBuffer: AsRef<[u8]> + AsMut<[u8]> + Sized {
316 type Kind: EvmCdBufferKind;
317
318 fn new(len: usize) -> Result<Self, Error>;
319}
320
321#[doc(hidden)]
322pub struct EvmCdBuffer<S> {
323 storage: core::mem::MaybeUninit<S>,
324}
325
326impl<S> EvmCdDecodeBuffer for EvmCdBuffer<S> {
327 type Kind = EvmCdStaticBufferKind;
328
329 fn new(len: usize) -> Result<Self, Error> {
330 if len > size_of::<S>() {
331 return Err(invalid_data());
332 }
333 let mut storage = core::mem::MaybeUninit::<S>::uninit();
334 unsafe {
337 storage
338 .as_mut_ptr()
339 .cast::<u8>()
340 .write_bytes(0, size_of::<S>())
341 };
342 Ok(Self { storage })
343 }
344}
345
346impl<S> AsRef<[u8]> for EvmCdBuffer<S> {
347 fn as_ref(&self) -> &[u8] {
348 unsafe { core::slice::from_raw_parts(self.storage.as_ptr().cast::<u8>(), size_of::<S>()) }
350 }
351}
352
353impl<S> AsMut<[u8]> for EvmCdBuffer<S> {
354 fn as_mut(&mut self) -> &mut [u8] {
355 unsafe {
357 core::slice::from_raw_parts_mut(self.storage.as_mut_ptr().cast::<u8>(), size_of::<S>())
358 }
359 }
360}
361
362#[cfg(feature = "alloc")]
363#[doc(hidden)]
364pub struct EvmCdDynamicBuffer<S>(pub Vec<u8>, pub core::marker::PhantomData<S>);
365
366#[cfg(feature = "alloc")]
367impl<S> EvmCdDecodeBuffer for EvmCdDynamicBuffer<S> {
368 type Kind = EvmCdDynamicBufferKind;
369
370 fn new(len: usize) -> Result<Self, Error> {
371 if len > MAX_ALLOC_DESERIALISE_LEN {
372 return Err(invalid_data());
373 }
374 let mut bytes = Vec::new();
375 bytes.try_reserve_exact(len).map_err(|_| invalid_data())?;
376 bytes.resize(len, 0);
377 Ok(Self(bytes, core::marker::PhantomData))
378 }
379}
380
381#[cfg(feature = "alloc")]
382impl<S> AsRef<[u8]> for EvmCdDynamicBuffer<S> {
383 fn as_ref(&self) -> &[u8] {
384 &self.0
385 }
386}
387
388#[cfg(feature = "alloc")]
389impl<S> AsMut<[u8]> for EvmCdDynamicBuffer<S> {
390 fn as_mut(&mut self) -> &mut [u8] {
391 &mut self.0
392 }
393}
394
395pub trait EvmCdDeserialise: Sized {
396 type Buffer: EvmCdDecodeBuffer;
397
398 fn new_buffer(len: usize) -> Result<Self::Buffer, Error> {
399 Self::Buffer::new(len)
400 }
401
402 fn deserialise<B>(bytes: &B) -> Result<Self, Error>
403 where
404 B: AsRef<[u8]> + ?Sized,
405 {
406 let mut reader = bytes.as_ref();
407 Self::deserialise_reader(&mut reader)
408 }
409
410 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error>;
411
412 #[doc(hidden)]
413 fn deserialise_value<R: Read>(reader: &mut R) -> Result<Self, Error> {
414 Self::deserialise_reader(reader)
415 }
416
417 #[doc(hidden)]
418 fn is_abi_dynamic() -> bool {
419 false
420 }
421
422 #[doc(hidden)]
423 fn abi_head_size() -> usize {
424 32
425 }
426
427 #[doc(hidden)]
428 fn abi_tail_size(&self) -> usize {
429 0
430 }
431
432 #[doc(hidden)]
433 fn deserialise_abi_head<R: Read>(reader: &mut R) -> Result<EvmCdHead<Self>, Error> {
434 Ok(EvmCdHead::Value(Self::deserialise_value(reader)?))
435 }
436
437 #[doc(hidden)]
438 fn deserialise_abi_finish<R: Read>(
439 head: EvmCdHead<Self>,
440 _expected_tail_offset: usize,
441 _reader: &mut R,
442 ) -> Result<Self, Error> {
443 match head {
444 EvmCdHead::Value(value) => Ok(value),
445 EvmCdHead::Offset(_) => Err(invalid_data()),
446 }
447 }
448
449 #[doc(hidden)]
450 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher;
451}
452
453#[cfg(not(feature = "std"))]
454pub fn invalid_data() -> Error {
455 Error::InvalidData
456}
457
458#[cfg(feature = "std")]
459pub fn invalid_data() -> Error {
460 Error::new(std::io::ErrorKind::InvalidData, "invalid EVM calldata")
461}
462
463fn read_usize_word<R: Read>(reader: &mut R) -> Result<usize, Error> {
464 let mut word = [0u8; 32];
465 reader.read_exact(&mut word)?;
466 if word[..32 - size_of::<usize>()]
467 .iter()
468 .any(|byte| *byte != 0)
469 {
470 return Err(invalid_data());
471 }
472 Ok(usize::from_be_bytes(
473 word[32 - size_of::<usize>()..].try_into().unwrap(),
474 ))
475}
476
477fn write_dynamic_tail<W: Write>(bytes: &[u8], writer: &mut W) -> Result<(), Error> {
478 writer.write_all(&U::from_usize(bytes.len()).0)?;
479 writer.write_all(bytes)?;
480 const ZEROES: [u8; 31] = [0; 31];
481 let padding = (32 - bytes.len() % 32) % 32;
482 writer.write_all(&ZEROES[..padding])
483}
484
485fn write_dynamic_bytes<W: Write>(bytes: &[u8], writer: &mut W) -> Result<(), Error> {
486 writer.write_all(&U::from_u32(32).0)?;
487 write_dynamic_tail(bytes, writer)
488}
489
490fn dynamic_tail_size(len: usize) -> usize {
491 32 + len + (32 - len % 32) % 32
492}
493
494fn read_dynamic_tail<const CAP: usize, R: Read>(
495 reader: &mut R,
496) -> Result<([u8; CAP], usize), Error> {
497 let len = read_usize_word(reader)?;
498 if len > CAP {
499 return Err(invalid_data());
500 }
501 let mut bytes = [0u8; CAP];
502 reader.read_exact(&mut bytes[..len])?;
503 let padding = (32 - len % 32) % 32;
504 let mut padding_bytes = [0u8; 31];
505 reader.read_exact(&mut padding_bytes[..padding])?;
506 if padding_bytes[..padding].iter().any(|byte| *byte != 0) {
507 return Err(invalid_data());
508 }
509 Ok((bytes, len))
510}
511
512fn read_dynamic_bytes<const CAP: usize, R: Read>(
513 reader: &mut R,
514) -> Result<([u8; CAP], usize), Error> {
515 if read_usize_word(reader)? != 32 {
516 return Err(invalid_data());
517 }
518 read_dynamic_tail(reader)
519}
520
521macro_rules! fixed_deserialise_buffer {
522 ($storage:ty) => {
523 type Buffer = EvmCdBuffer<$storage>;
524 };
525}
526
527impl EvmCdSerialise for U {
528 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
529 writer.write_all(&self.0)
530 }
531
532 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
533 hasher.update(b"uint256")
534 }
535}
536
537impl EvmCdDeserialise for U {
538 fixed_deserialise_buffer!([u8; 32]);
539
540 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
541 let mut buf = [0u8; 32];
542 reader.read_exact(&mut buf)?;
543 Ok(U(buf))
544 }
545
546 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
547 hasher.update(b"uint256")
548 }
549}
550
551impl EvmCdSerialise for bool {
552 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
553 u8::from(*self).serialise_value(writer)
554 }
555
556 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
557 hasher.update(b"bool")
558 }
559}
560
561impl EvmCdDeserialise for bool {
562 fixed_deserialise_buffer!([u8; 32]);
563
564 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
565 match u8::deserialise_reader(reader)? {
566 0 => Ok(false),
567 1 => Ok(true),
568 _ => Err(invalid_data()),
569 }
570 }
571
572 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
573 hasher.update(b"bool")
574 }
575}
576
577macro_rules! for_ints {
578 ($($ty:ty => $abi:literal),+ $(,)?) => {
579 $(
580 impl EvmCdSerialise for $ty {
581 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
582 writer.write_all(&[0u8; 32 - size_of::<$ty>()])?;
583 writer.write_all(&self.to_be_bytes())
584 }
585
586 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
587 hasher.update($abi)
588 }
589 }
590
591 impl EvmCdDeserialise for $ty {
592 fixed_deserialise_buffer!([u8; 32]);
593
594 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
595 let U(word) = U::deserialise_reader(reader)?;
596 if word[..32 - size_of::<$ty>()].iter().any(|byte| *byte != 0) {
597 return Err(invalid_data());
598 }
599 Ok(<$ty>::from_be_bytes(
600 word[32 - size_of::<$ty>()..].try_into().unwrap(),
601 ))
602 }
603
604 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
605 hasher.update($abi)
606 }
607 }
608 )+
609 };
610}
611
612for_ints! {
613 u8 => b"uint8",
614 u16 => b"uint16",
615 u32 => b"uint32",
616 u64 => b"uint64",
617 u128 => b"uint128",
618}
619
620macro_rules! for_signed_ints {
621 ($($ty:ty => $abi:literal),+ $(,)?) => {
622 $(
623 impl EvmCdSerialise for $ty {
624 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
625 let extension = if self.is_negative() { 0xff } else { 0 };
626 writer.write_all(&[extension; 32 - size_of::<$ty>()])?;
627 writer.write_all(&self.to_be_bytes())
628 }
629
630 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
631 hasher.update($abi)
632 }
633 }
634
635 impl EvmCdDeserialise for $ty {
636 fixed_deserialise_buffer!([u8; 32]);
637
638 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
639 let mut word = [0u8; 32];
640 reader.read_exact(&mut word)?;
641 let value_start = 32 - size_of::<$ty>();
642 let extension = if word[value_start] & 0x80 == 0 { 0 } else { 0xff };
643 if word[..value_start].iter().any(|byte| *byte != extension) {
644 return Err(invalid_data());
645 }
646 Ok(<$ty>::from_be_bytes(word[value_start..].try_into().unwrap()))
647 }
648
649 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
650 hasher.update($abi)
651 }
652 }
653 )+
654 };
655}
656
657for_signed_ints! {
658 i8 => b"int8",
659 i16 => b"int16",
660 i32 => b"int32",
661 i64 => b"int64",
662 i128 => b"int128",
663}
664
665impl EvmCdSerialise for usize {
666 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
667 <u32 as EvmCdSerialise>::serialise_value(
668 &u32::try_from(*self).map_err(|_| invalid_data())?,
669 writer,
670 )
671 }
672
673 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
674 hasher.update(b"uint32")
675 }
676}
677
678impl EvmCdDeserialise for usize {
679 fixed_deserialise_buffer!([u8; 32]);
680
681 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
682 Ok(u32::deserialise_reader(reader)? as usize)
683 }
684
685 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
686 hasher.update(b"uint32")
687 }
688}
689
690macro_rules! evm_cd_uint {
691 ($name:ident, $bits:literal, $bytes:literal) => {
692 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
693 pub struct $name(pub [u8; $bytes]);
694
695 impl $name {
696 pub const fn new(bytes: [u8; $bytes]) -> Self {
697 Self(bytes)
698 }
699
700 pub const fn into_array(self) -> [u8; $bytes] {
701 self.0
702 }
703
704 pub const fn as_array(&self) -> &[u8; $bytes] {
705 &self.0
706 }
707 }
708
709 impl From<[u8; $bytes]> for $name {
710 fn from(bytes: [u8; $bytes]) -> Self {
711 Self::new(bytes)
712 }
713 }
714
715 impl From<$name> for [u8; $bytes] {
716 fn from(value: $name) -> Self {
717 value.into_array()
718 }
719 }
720
721 impl From<$name> for U {
722 fn from(value: $name) -> Self {
723 let mut word = [0u8; 32];
724 word[32 - $bytes..].copy_from_slice(value.as_array());
725 Self::from(word)
726 }
727 }
728
729 impl From<U> for $name {
730 fn from(value: U) -> Self {
731 let word: [u8; 32] = value.into();
732 Self::new(word[32 - $bytes..].try_into().unwrap())
733 }
734 }
735
736 impl AsRef<[u8; $bytes]> for $name {
737 fn as_ref(&self) -> &[u8; $bytes] {
738 self.as_array()
739 }
740 }
741
742 impl AsRef<[u8]> for $name {
743 fn as_ref(&self) -> &[u8] {
744 self.as_array()
745 }
746 }
747
748 impl EvmCdSerialise for $name {
749 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
750 writer.write_all(&[0; 32 - $bytes])?;
751 writer.write_all(&self.0)
752 }
753
754 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
755 hasher.update(b"uint").update_usize($bits)
756 }
757 }
758
759 impl EvmCdDeserialise for $name {
760 fixed_deserialise_buffer!([u8; 32]);
761
762 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
763 let mut word = [0u8; 32];
764 reader.read_exact(&mut word)?;
765 if word[..32 - $bytes].iter().any(|byte| *byte != 0) {
766 return Err(invalid_data());
767 }
768 Ok(Self(word[32 - $bytes..].try_into().unwrap()))
769 }
770
771 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
772 hasher.update(b"uint").update_usize($bits)
773 }
774 }
775 };
776}
777
778macro_rules! evm_cd_int {
779 ($name:ident, $bits:literal, $bytes:literal) => {
780 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
781 pub struct $name(pub [u8; $bytes]);
782
783 impl $name {
784 pub const fn new(bytes: [u8; $bytes]) -> Self {
785 Self(bytes)
786 }
787
788 pub const fn into_array(self) -> [u8; $bytes] {
789 self.0
790 }
791
792 pub const fn as_array(&self) -> &[u8; $bytes] {
793 &self.0
794 }
795 }
796
797 impl From<[u8; $bytes]> for $name {
798 fn from(bytes: [u8; $bytes]) -> Self {
799 Self::new(bytes)
800 }
801 }
802
803 impl From<$name> for [u8; $bytes] {
804 fn from(value: $name) -> Self {
805 value.into_array()
806 }
807 }
808
809 impl From<$name> for I {
810 fn from(value: $name) -> Self {
811 let extension = if value.0[0] & 0x80 == 0 { 0 } else { 0xff };
812 let mut word = [extension; 32];
813 word[32 - $bytes..].copy_from_slice(value.as_array());
814 Self::from(word)
815 }
816 }
817
818 impl From<I> for $name {
819 fn from(value: I) -> Self {
820 let word: [u8; 32] = value.into();
821 Self::new(word[32 - $bytes..].try_into().unwrap())
822 }
823 }
824
825 impl AsRef<[u8; $bytes]> for $name {
826 fn as_ref(&self) -> &[u8; $bytes] {
827 self.as_array()
828 }
829 }
830
831 impl AsRef<[u8]> for $name {
832 fn as_ref(&self) -> &[u8] {
833 self.as_array()
834 }
835 }
836
837 impl EvmCdSerialise for $name {
838 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
839 let extension = if self.0[0] & 0x80 == 0 { 0 } else { 0xff };
840 writer.write_all(&[extension; 32 - $bytes])?;
841 writer.write_all(&self.0)
842 }
843
844 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
845 hasher.update(b"int").update_usize($bits)
846 }
847 }
848
849 impl EvmCdDeserialise for $name {
850 fixed_deserialise_buffer!([u8; 32]);
851
852 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
853 let mut word = [0u8; 32];
854 reader.read_exact(&mut word)?;
855 let extension = if word[32 - $bytes] & 0x80 == 0 {
856 0
857 } else {
858 0xff
859 };
860 if word[..32 - $bytes].iter().any(|byte| *byte != extension) {
861 return Err(invalid_data());
862 }
863 Ok(Self(word[32 - $bytes..].try_into().unwrap()))
864 }
865
866 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
867 hasher.update(b"int").update_usize($bits)
868 }
869 }
870 };
871}
872
873macro_rules! evm_cd_integer_range {
874 ($uint_macro:ident, $int_macro:ident) => {
875 $uint_macro!(EvmCdU24, 24, 3);
876 $int_macro!(EvmCdI24, 24, 3);
877 $uint_macro!(EvmCdU40, 40, 5);
878 $int_macro!(EvmCdI40, 40, 5);
879 $uint_macro!(EvmCdU48, 48, 6);
880 $int_macro!(EvmCdI48, 48, 6);
881 $uint_macro!(EvmCdU56, 56, 7);
882 $int_macro!(EvmCdI56, 56, 7);
883 $uint_macro!(EvmCdU72, 72, 9);
884 $int_macro!(EvmCdI72, 72, 9);
885 $uint_macro!(EvmCdU80, 80, 10);
886 $int_macro!(EvmCdI80, 80, 10);
887 $uint_macro!(EvmCdU88, 88, 11);
888 $int_macro!(EvmCdI88, 88, 11);
889 $uint_macro!(EvmCdU96, 96, 12);
890 $int_macro!(EvmCdI96, 96, 12);
891 $uint_macro!(EvmCdU104, 104, 13);
892 $int_macro!(EvmCdI104, 104, 13);
893 $uint_macro!(EvmCdU112, 112, 14);
894 $int_macro!(EvmCdI112, 112, 14);
895 $uint_macro!(EvmCdU120, 120, 15);
896 $int_macro!(EvmCdI120, 120, 15);
897 $uint_macro!(EvmCdU136, 136, 17);
898 $int_macro!(EvmCdI136, 136, 17);
899 $uint_macro!(EvmCdU144, 144, 18);
900 $int_macro!(EvmCdI144, 144, 18);
901 $uint_macro!(EvmCdU152, 152, 19);
902 $int_macro!(EvmCdI152, 152, 19);
903 $uint_macro!(EvmCdU160, 160, 20);
904 $int_macro!(EvmCdI160, 160, 20);
905 $uint_macro!(EvmCdU168, 168, 21);
906 $int_macro!(EvmCdI168, 168, 21);
907 $uint_macro!(EvmCdU176, 176, 22);
908 $int_macro!(EvmCdI176, 176, 22);
909 $uint_macro!(EvmCdU184, 184, 23);
910 $int_macro!(EvmCdI184, 184, 23);
911 $uint_macro!(EvmCdU192, 192, 24);
912 $int_macro!(EvmCdI192, 192, 24);
913 $uint_macro!(EvmCdU200, 200, 25);
914 $int_macro!(EvmCdI200, 200, 25);
915 $uint_macro!(EvmCdU208, 208, 26);
916 $int_macro!(EvmCdI208, 208, 26);
917 $uint_macro!(EvmCdU216, 216, 27);
918 $int_macro!(EvmCdI216, 216, 27);
919 $uint_macro!(EvmCdU224, 224, 28);
920 $int_macro!(EvmCdI224, 224, 28);
921 $uint_macro!(EvmCdU232, 232, 29);
922 $int_macro!(EvmCdI232, 232, 29);
923 $uint_macro!(EvmCdU240, 240, 30);
924 $int_macro!(EvmCdI240, 240, 30);
925 $uint_macro!(EvmCdU248, 248, 31);
926 $int_macro!(EvmCdI248, 248, 31);
927 $uint_macro!(EvmCdU256, 256, 32);
928 $int_macro!(EvmCdI256, 256, 32);
929 };
930}
931
932evm_cd_integer_range!(evm_cd_uint, evm_cd_int);
933
934#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
935pub struct EvmCdAddress(pub [u8; 20]);
936
937impl EvmCdAddress {
938 pub const fn new(bytes: [u8; 20]) -> Self {
939 Self(bytes)
940 }
941
942 pub const fn into_array(self) -> [u8; 20] {
943 self.0
944 }
945
946 pub const fn as_array(&self) -> &[u8; 20] {
947 &self.0
948 }
949}
950
951impl From<[u8; 20]> for EvmCdAddress {
952 fn from(bytes: [u8; 20]) -> Self {
953 Self::new(bytes)
954 }
955}
956
957impl From<EvmCdAddress> for [u8; 20] {
958 fn from(address: EvmCdAddress) -> Self {
959 address.into_array()
960 }
961}
962
963impl From<EvmCdAddress> for U {
964 fn from(address: EvmCdAddress) -> Self {
965 let mut word = [0u8; 32];
966 word[12..].copy_from_slice(address.as_array());
967 Self::from(word)
968 }
969}
970
971impl AsRef<[u8; 20]> for EvmCdAddress {
972 fn as_ref(&self) -> &[u8; 20] {
973 self.as_array()
974 }
975}
976
977impl AsRef<[u8]> for EvmCdAddress {
978 fn as_ref(&self) -> &[u8] {
979 self.as_array()
980 }
981}
982
983impl EvmCdSerialise for EvmCdAddress {
984 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
985 writer.write_all(&[0; 12])?;
986 writer.write_all(&self.0)
987 }
988
989 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
990 hasher.update(b"address")
991 }
992}
993
994impl EvmCdDeserialise for EvmCdAddress {
995 fixed_deserialise_buffer!([u8; 32]);
996
997 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
998 let mut word = [0u8; 32];
999 reader.read_exact(&mut word)?;
1000 if word[..12].iter().any(|byte| *byte != 0) {
1001 return Err(invalid_data());
1002 }
1003 Ok(Self(word[12..].try_into().unwrap()))
1004 }
1005
1006 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1007 hasher.update(b"address")
1008 }
1009}
1010
1011impl<const N: usize> EvmCdSerialise for [u8; N] {
1012 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1013 if N == 0 || N > 32 {
1014 return Err(invalid_data());
1015 }
1016 writer.write_all(self)?;
1017 const ZEROES: [u8; 32] = [0; 32];
1018 writer.write_all(&ZEROES[..32 - N])
1019 }
1020
1021 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1022 hasher.update(b"bytes").update_usize(N)
1023 }
1024}
1025
1026impl<const N: usize> EvmCdDeserialise for [u8; N] {
1027 fixed_deserialise_buffer!([u8; 32]);
1028
1029 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
1030 if N == 0 || N > 32 {
1031 return Err(invalid_data());
1032 }
1033 let mut word = [0u8; 32];
1034 reader.read_exact(&mut word)?;
1035 if word[N..].iter().any(|byte| *byte != 0) {
1036 return Err(invalid_data());
1037 }
1038 Ok(word[..N].try_into().unwrap())
1039 }
1040
1041 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1042 hasher.update(b"bytes").update_usize(N)
1043 }
1044}
1045
1046#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1047pub enum EvmCdArrayError {
1048 InvalidBounds,
1049 TooShort,
1050 TooLong,
1051}
1052
1053pub struct EvmCdArray<T, const MIN: usize, const CAP: usize> {
1054 len: usize,
1055 values: [core::mem::MaybeUninit<T>; CAP],
1056}
1057
1058impl<T, const MIN: usize, const CAP: usize> EvmCdArray<T, MIN, CAP> {
1059 fn empty() -> Self {
1060 Self {
1061 len: 0,
1062 values: [const { core::mem::MaybeUninit::uninit() }; CAP],
1063 }
1064 }
1065
1066 fn validate_len(len: usize) -> Result<(), EvmCdArrayError> {
1067 if MIN > CAP {
1068 return Err(EvmCdArrayError::InvalidBounds);
1069 }
1070 if len < MIN {
1071 return Err(EvmCdArrayError::TooShort);
1072 }
1073 if len > CAP {
1074 return Err(EvmCdArrayError::TooLong);
1075 }
1076 Ok(())
1077 }
1078
1079 fn push(&mut self, value: T) {
1080 debug_assert!(self.len < CAP);
1081 self.values[self.len].write(value);
1082 self.len += 1;
1083 }
1084
1085 pub fn try_from_array(values: [T; CAP], len: usize) -> Result<Self, EvmCdArrayError> {
1086 Self::validate_len(len)?;
1087 let mut out = Self::empty();
1088 for value in values.into_iter().take(len) {
1089 out.push(value);
1090 }
1091 Ok(out)
1092 }
1093
1094 pub fn try_from_slice(values: &[T]) -> Result<Self, EvmCdArrayError>
1095 where
1096 T: Clone,
1097 {
1098 Self::validate_len(values.len())?;
1099 let mut out = Self::empty();
1100 for value in values {
1101 out.push(value.clone());
1102 }
1103 Ok(out)
1104 }
1105
1106 pub const fn len(&self) -> usize {
1107 self.len
1108 }
1109
1110 pub const fn is_empty(&self) -> bool {
1111 self.len == 0
1112 }
1113
1114 pub const fn capacity(&self) -> usize {
1115 CAP
1116 }
1117
1118 pub fn as_slice(&self) -> &[T] {
1119 unsafe { core::slice::from_raw_parts(self.values.as_ptr().cast::<T>(), self.len) }
1122 }
1123}
1124
1125impl<T, const MIN: usize, const CAP: usize> Drop for EvmCdArray<T, MIN, CAP> {
1126 fn drop(&mut self) {
1127 for value in &mut self.values[..self.len] {
1128 unsafe { value.assume_init_drop() };
1130 }
1131 }
1132}
1133
1134impl<T: Clone, const MIN: usize, const CAP: usize> Clone for EvmCdArray<T, MIN, CAP> {
1135 fn clone(&self) -> Self {
1136 Self::try_from_slice(self.as_slice()).expect("an existing EvmCdArray has valid bounds")
1137 }
1138}
1139
1140impl<T: core::fmt::Debug, const MIN: usize, const CAP: usize> core::fmt::Debug
1141 for EvmCdArray<T, MIN, CAP>
1142{
1143 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1144 formatter.debug_list().entries(self.as_slice()).finish()
1145 }
1146}
1147
1148impl<T: PartialEq, const MIN: usize, const CAP: usize> PartialEq for EvmCdArray<T, MIN, CAP> {
1149 fn eq(&self, other: &Self) -> bool {
1150 self.as_slice() == other.as_slice()
1151 }
1152}
1153
1154impl<T: Eq, const MIN: usize, const CAP: usize> Eq for EvmCdArray<T, MIN, CAP> {}
1155
1156impl<T, const MIN: usize, const CAP: usize> AsRef<[T]> for EvmCdArray<T, MIN, CAP> {
1157 fn as_ref(&self) -> &[T] {
1158 self.as_slice()
1159 }
1160}
1161
1162impl<T> EvmCdSerialise for &[T]
1163where
1164 T: EvmCdSerialise,
1165{
1166 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1167 U::from_u32(32).serialise_value(writer)?;
1168 self.serialise_abi_tail(writer)
1169 }
1170
1171 fn is_abi_dynamic() -> bool {
1172 true
1173 }
1174
1175 fn abi_tail_size(&self) -> usize {
1176 self.len()
1177 .saturating_mul(T::abi_head_size())
1178 .saturating_add(32)
1179 .saturating_add(self.iter().fold(0usize, |size, value| {
1180 size.saturating_add(value.abi_tail_size())
1181 }))
1182 }
1183
1184 fn serialise_abi_head<W: Write>(
1185 &self,
1186 tail_offset: usize,
1187 writer: &mut W,
1188 ) -> Result<(), Error> {
1189 U::from_usize(tail_offset).serialise_value(writer)
1190 }
1191
1192 fn serialise_abi_tail<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1193 U::from_usize(self.len()).serialise_value(writer)?;
1194 let mut tail_offset = self
1195 .len()
1196 .checked_mul(T::abi_head_size())
1197 .ok_or_else(invalid_data)?;
1198 for value in *self {
1199 value.serialise_abi_head(tail_offset, writer)?;
1200 tail_offset = tail_offset
1201 .checked_add(value.abi_tail_size())
1202 .ok_or_else(invalid_data)?;
1203 }
1204 for value in *self {
1205 value.serialise_abi_tail(writer)?;
1206 }
1207 Ok(())
1208 }
1209
1210 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1211 T::append_abi_type(hasher).update(b"[]")
1212 }
1213}
1214
1215impl<T, const MIN: usize, const CAP: usize> EvmCdSerialise for EvmCdArray<T, MIN, CAP>
1216where
1217 T: EvmCdSerialise,
1218{
1219 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1220 U::from_u32(32).serialise_value(writer)?;
1221 self.serialise_abi_tail(writer)
1222 }
1223
1224 fn is_abi_dynamic() -> bool {
1225 true
1226 }
1227
1228 fn abi_tail_size(&self) -> usize {
1229 self.len
1230 .saturating_mul(T::abi_head_size())
1231 .saturating_add(32)
1232 .saturating_add(self.as_slice().iter().fold(0usize, |size, value| {
1233 size.saturating_add(value.abi_tail_size())
1234 }))
1235 }
1236
1237 fn serialise_abi_head<W: Write>(
1238 &self,
1239 tail_offset: usize,
1240 writer: &mut W,
1241 ) -> Result<(), Error> {
1242 U::from_usize(tail_offset).serialise_value(writer)
1243 }
1244
1245 fn serialise_abi_tail<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1246 U::from_usize(self.len).serialise_value(writer)?;
1247 let mut tail_offset = self
1248 .len
1249 .checked_mul(T::abi_head_size())
1250 .ok_or_else(invalid_data)?;
1251 for value in self.as_slice() {
1252 value.serialise_abi_head(tail_offset, writer)?;
1253 tail_offset = tail_offset
1254 .checked_add(value.abi_tail_size())
1255 .ok_or_else(invalid_data)?;
1256 }
1257 for value in self.as_slice() {
1258 value.serialise_abi_tail(writer)?;
1259 }
1260 Ok(())
1261 }
1262
1263 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1264 T::append_abi_type(hasher).update(b"[]")
1265 }
1266}
1267
1268impl<T, const MIN: usize, const CAP: usize> EvmCdDeserialise for EvmCdArray<T, MIN, CAP>
1269where
1270 T: EvmCdDeserialise,
1271{
1272 type Buffer = <<T::Buffer as EvmCdDecodeBuffer>::Kind as EvmCdBufferKind>::Buffer<(
1273 [u8; 64],
1274 [T::Buffer; CAP],
1275 )>;
1276
1277 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
1278 if read_usize_word(reader)? != 32 {
1279 return Err(invalid_data());
1280 }
1281 Self::deserialise_tail(reader)
1282 }
1283
1284 fn is_abi_dynamic() -> bool {
1285 true
1286 }
1287
1288 fn abi_tail_size(&self) -> usize {
1289 self.len
1290 .saturating_mul(T::abi_head_size())
1291 .saturating_add(32)
1292 .saturating_add(self.as_slice().iter().fold(0usize, |size, value| {
1293 size.saturating_add(value.abi_tail_size())
1294 }))
1295 }
1296
1297 fn deserialise_abi_head<R: Read>(reader: &mut R) -> Result<EvmCdHead<Self>, Error> {
1298 Ok(EvmCdHead::Offset(read_usize_word(reader)?))
1299 }
1300
1301 fn deserialise_abi_finish<R: Read>(
1302 head: EvmCdHead<Self>,
1303 expected_tail_offset: usize,
1304 reader: &mut R,
1305 ) -> Result<Self, Error> {
1306 match head {
1307 EvmCdHead::Offset(offset) if offset == expected_tail_offset => {
1308 Self::deserialise_tail(reader)
1309 }
1310 _ => Err(invalid_data()),
1311 }
1312 }
1313
1314 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1315 T::append_abi_type(hasher).update(b"[]")
1316 }
1317}
1318
1319impl<T, const MIN: usize, const CAP: usize> EvmCdArray<T, MIN, CAP>
1320where
1321 T: EvmCdDeserialise,
1322{
1323 fn deserialise_tail<R: Read>(reader: &mut R) -> Result<Self, Error> {
1324 let len = read_usize_word(reader)?;
1325 Self::validate_len(len).map_err(|_| invalid_data())?;
1326 let mut out = Self::empty();
1327
1328 if T::is_abi_dynamic() {
1329 let mut offsets = [0usize; CAP];
1330 for offset in &mut offsets[..len] {
1331 match T::deserialise_abi_head(reader)? {
1332 EvmCdHead::Offset(value) => *offset = value,
1333 EvmCdHead::Value(_) => return Err(invalid_data()),
1334 }
1335 }
1336 let mut expected_tail_offset = len
1337 .checked_mul(T::abi_head_size())
1338 .ok_or_else(invalid_data)?;
1339 for offset in offsets[..len].iter().copied() {
1340 let value = T::deserialise_abi_finish(
1341 EvmCdHead::Offset(offset),
1342 expected_tail_offset,
1343 reader,
1344 )?;
1345 expected_tail_offset = expected_tail_offset
1346 .checked_add(value.abi_tail_size())
1347 .ok_or_else(invalid_data)?;
1348 out.push(value);
1349 }
1350 } else {
1351 for _ in 0..len {
1352 let head = T::deserialise_abi_head(reader)?;
1353 out.push(T::deserialise_abi_finish(head, 0, reader)?);
1354 }
1355 }
1356 Ok(out)
1357 }
1358}
1359
1360#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1361pub enum EvmCdBytesError {
1362 TooLong,
1363}
1364
1365#[derive(Clone)]
1366pub struct EvmCdBytes<const CAP: usize> {
1367 pub len: usize,
1368 pub bytes: [u8; CAP],
1369}
1370
1371impl<const CAP: usize> EvmCdBytes<CAP> {
1372 pub const fn new() -> Self {
1373 Self {
1374 len: 0,
1375 bytes: [0; CAP],
1376 }
1377 }
1378
1379 pub fn try_from_slice(value: &[u8]) -> Result<Self, EvmCdBytesError> {
1380 if value.len() > CAP {
1381 return Err(EvmCdBytesError::TooLong);
1382 }
1383 let mut bytes = [0; CAP];
1384 bytes[..value.len()].copy_from_slice(value);
1385 Ok(Self {
1386 len: value.len(),
1387 bytes,
1388 })
1389 }
1390
1391 pub fn try_from_serialised<T: EvmCdSerialise + ?Sized>(value: &T) -> Result<Self, Error> {
1392 let mut bytes = Self::new();
1393 value.serialise(&mut bytes)?;
1394 Ok(bytes)
1395 }
1396
1397 pub const fn len(&self) -> usize {
1398 self.len
1399 }
1400
1401 pub const fn is_empty(&self) -> bool {
1402 self.len == 0
1403 }
1404
1405 pub const fn capacity(&self) -> usize {
1406 CAP
1407 }
1408
1409 pub fn as_slice(&self) -> &[u8] {
1410 &self.bytes[..self.len]
1411 }
1412
1413 pub fn clear(&mut self) {
1414 self.len = 0;
1415 }
1416
1417 pub fn extend_from_slice(&mut self, value: &[u8]) -> Result<(), EvmCdBytesError> {
1418 let end = self
1419 .len
1420 .checked_add(value.len())
1421 .filter(|end| *end <= CAP)
1422 .ok_or(EvmCdBytesError::TooLong)?;
1423 self.bytes[self.len..end].copy_from_slice(value);
1424 self.len = end;
1425 Ok(())
1426 }
1427}
1428
1429impl<const CAP: usize> Default for EvmCdBytes<CAP> {
1430 fn default() -> Self {
1431 Self::new()
1432 }
1433}
1434
1435impl<const CAP: usize> From<[u8; CAP]> for EvmCdBytes<CAP> {
1436 fn from(bytes: [u8; CAP]) -> Self {
1437 Self { len: CAP, bytes }
1438 }
1439}
1440
1441impl<const CAP: usize> TryFrom<&[u8]> for EvmCdBytes<CAP> {
1442 type Error = EvmCdBytesError;
1443
1444 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
1445 Self::try_from_slice(value)
1446 }
1447}
1448
1449#[cfg(feature = "alloc")]
1450impl<const CAP: usize> TryFrom<Vec<u8>> for EvmCdBytes<CAP> {
1451 type Error = EvmCdBytesError;
1452
1453 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
1454 Self::try_from_slice(&value)
1455 }
1456}
1457
1458impl<const CAP: usize> AsRef<[u8]> for EvmCdBytes<CAP> {
1459 fn as_ref(&self) -> &[u8] {
1460 self.as_slice()
1461 }
1462}
1463
1464impl<const CAP: usize> core::fmt::Debug for EvmCdBytes<CAP> {
1465 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1466 core::fmt::Debug::fmt(self.as_slice(), formatter)
1467 }
1468}
1469
1470impl<const CAP: usize> PartialEq for EvmCdBytes<CAP> {
1471 fn eq(&self, other: &Self) -> bool {
1472 self.as_slice() == other.as_slice()
1473 }
1474}
1475
1476impl<const CAP: usize> Eq for EvmCdBytes<CAP> {}
1477
1478impl<const CAP: usize> PartialOrd for EvmCdBytes<CAP> {
1479 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1480 Some(self.cmp(other))
1481 }
1482}
1483
1484impl<const CAP: usize> Ord for EvmCdBytes<CAP> {
1485 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1486 self.as_slice().cmp(other.as_slice())
1487 }
1488}
1489
1490impl<const CAP: usize> core::hash::Hash for EvmCdBytes<CAP> {
1491 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1492 core::hash::Hash::hash(self.as_slice(), state)
1493 }
1494}
1495
1496#[doc(hidden)]
1497pub struct EvmCdBytesWriter<'a, const CAP: usize> {
1498 pub bytes: &'a mut EvmCdBytes<CAP>,
1499}
1500
1501#[cfg(not(feature = "std"))]
1502impl<const CAP: usize> Write for EvmCdBytesWriter<'_, CAP> {
1503 fn write(&mut self, value: &[u8]) -> Result<usize, Error> {
1504 let written = core::cmp::min(CAP - self.bytes.len, value.len());
1505 let end = self.bytes.len + written;
1506 self.bytes.bytes[self.bytes.len..end].copy_from_slice(&value[..written]);
1507 self.bytes.len = end;
1508 Ok(written)
1509 }
1510
1511 fn flush(&mut self) -> Result<(), Error> {
1512 Ok(())
1513 }
1514
1515 fn is_empty(&self) -> bool {
1516 self.bytes.len == CAP
1517 }
1518}
1519
1520#[cfg(feature = "std")]
1521impl<const CAP: usize> Write for EvmCdBytesWriter<'_, CAP> {
1522 fn write(&mut self, value: &[u8]) -> Result<usize, Error> {
1523 let written = core::cmp::min(CAP - self.bytes.len, value.len());
1524 let end = self.bytes.len + written;
1525 self.bytes.bytes[self.bytes.len..end].copy_from_slice(&value[..written]);
1526 self.bytes.len = end;
1527 Ok(written)
1528 }
1529
1530 fn flush(&mut self) -> Result<(), Error> {
1531 Ok(())
1532 }
1533}
1534
1535impl<const CAP: usize> EvmCdWriteTarget for EvmCdBytes<CAP> {
1536 type Writer<'a> = EvmCdBytesWriter<'a, CAP>;
1537
1538 fn writer(&mut self) -> Self::Writer<'_> {
1539 EvmCdBytesWriter { bytes: self }
1540 }
1541}
1542
1543impl<const CAP: usize> EvmCdSerialise for EvmCdBytes<CAP> {
1544 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1545 write_dynamic_bytes(self.as_slice(), writer)
1546 }
1547
1548 fn is_abi_dynamic() -> bool {
1549 true
1550 }
1551
1552 fn abi_tail_size(&self) -> usize {
1553 dynamic_tail_size(self.len)
1554 }
1555
1556 fn serialise_abi_head<W: Write>(
1557 &self,
1558 tail_offset: usize,
1559 writer: &mut W,
1560 ) -> Result<(), Error> {
1561 U::from_usize(tail_offset).serialise_value(writer)
1562 }
1563
1564 fn serialise_abi_tail<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1565 write_dynamic_tail(self.as_slice(), writer)
1566 }
1567
1568 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1569 hasher.update(b"bytes")
1570 }
1571}
1572
1573impl<const CAP: usize> EvmCdDeserialise for EvmCdBytes<CAP> {
1574 type Buffer = EvmCdBuffer<([u8; 64], [u8; CAP], [u8; 31])>;
1575
1576 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
1577 let (bytes, len) = read_dynamic_bytes::<CAP, _>(reader)?;
1578 Ok(Self { len, bytes })
1579 }
1580
1581 fn is_abi_dynamic() -> bool {
1582 true
1583 }
1584
1585 fn abi_tail_size(&self) -> usize {
1586 dynamic_tail_size(self.len)
1587 }
1588
1589 fn deserialise_abi_head<R: Read>(reader: &mut R) -> Result<EvmCdHead<Self>, Error> {
1590 Ok(EvmCdHead::Offset(read_usize_word(reader)?))
1591 }
1592
1593 fn deserialise_abi_finish<R: Read>(
1594 head: EvmCdHead<Self>,
1595 expected_tail_offset: usize,
1596 reader: &mut R,
1597 ) -> Result<Self, Error> {
1598 match head {
1599 EvmCdHead::Offset(offset) if offset == expected_tail_offset => {
1600 let (bytes, len) = read_dynamic_tail::<CAP, _>(reader)?;
1601 Ok(Self { len, bytes })
1602 }
1603 _ => Err(invalid_data()),
1604 }
1605 }
1606
1607 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1608 hasher.update(b"bytes")
1609 }
1610}
1611
1612#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1613pub enum EvmCdStringError {
1614 InvalidBounds,
1615 TooShort,
1616 TooLong,
1617}
1618
1619#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1620pub struct EvmCdString<const MIN: usize, const CAP: usize> {
1621 pub len: usize,
1622 pub bytes: [u8; CAP],
1623}
1624
1625impl<const MIN: usize, const CAP: usize> EvmCdString<MIN, CAP> {
1626 pub fn try_from_str(value: &str) -> Result<Self, EvmCdStringError> {
1627 if MIN > CAP {
1628 return Err(EvmCdStringError::InvalidBounds);
1629 }
1630 if value.len() < MIN {
1631 return Err(EvmCdStringError::TooShort);
1632 }
1633 if value.len() > CAP {
1634 return Err(EvmCdStringError::TooLong);
1635 }
1636 let mut bytes = [0u8; CAP];
1637 bytes[..value.len()].copy_from_slice(value.as_bytes());
1638 Ok(Self {
1639 len: value.len(),
1640 bytes,
1641 })
1642 }
1643
1644 pub const fn len(&self) -> usize {
1645 self.len
1646 }
1647
1648 pub const fn is_empty(&self) -> bool {
1649 self.len == 0
1650 }
1651
1652 pub const fn capacity(&self) -> usize {
1653 CAP
1654 }
1655
1656 pub fn as_bytes(&self) -> &[u8] {
1657 &self.bytes[..self.len]
1658 }
1659
1660 pub fn as_str(&self) -> &str {
1661 unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
1664 }
1665}
1666
1667impl<const MIN: usize, const CAP: usize> TryFrom<&str> for EvmCdString<MIN, CAP> {
1668 type Error = EvmCdStringError;
1669
1670 fn try_from(value: &str) -> Result<Self, Self::Error> {
1671 Self::try_from_str(value)
1672 }
1673}
1674
1675impl<const MIN: usize, const CAP: usize> AsRef<str> for EvmCdString<MIN, CAP> {
1676 fn as_ref(&self) -> &str {
1677 self.as_str()
1678 }
1679}
1680
1681impl<const MIN: usize, const CAP: usize> AsRef<[u8]> for EvmCdString<MIN, CAP> {
1682 fn as_ref(&self) -> &[u8] {
1683 self.as_bytes()
1684 }
1685}
1686
1687impl<const MIN: usize, const CAP: usize> core::borrow::Borrow<str> for EvmCdString<MIN, CAP> {
1688 fn borrow(&self) -> &str {
1689 self.as_str()
1690 }
1691}
1692
1693impl<const MIN: usize, const CAP: usize> core::fmt::Display for EvmCdString<MIN, CAP> {
1694 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1695 formatter.write_str(self.as_str())
1696 }
1697}
1698
1699impl<const MIN: usize, const CAP: usize> core::fmt::Debug for EvmCdString<MIN, CAP> {
1700 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1701 core::fmt::Debug::fmt(self.as_str(), formatter)
1702 }
1703}
1704
1705impl<const MIN: usize, const CAP: usize> core::str::FromStr for EvmCdString<MIN, CAP> {
1706 type Err = EvmCdStringError;
1707
1708 fn from_str(value: &str) -> Result<Self, Self::Err> {
1709 Self::try_from_str(value)
1710 }
1711}
1712
1713impl<const MIN: usize, const CAP: usize> EvmCdSerialise for EvmCdString<MIN, CAP> {
1714 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1715 write_dynamic_bytes(self.as_bytes(), writer)
1716 }
1717
1718 fn is_abi_dynamic() -> bool {
1719 true
1720 }
1721
1722 fn abi_tail_size(&self) -> usize {
1723 dynamic_tail_size(self.len)
1724 }
1725
1726 fn serialise_abi_head<W: Write>(
1727 &self,
1728 tail_offset: usize,
1729 writer: &mut W,
1730 ) -> Result<(), Error> {
1731 U::from_usize(tail_offset).serialise_value(writer)
1732 }
1733
1734 fn serialise_abi_tail<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1735 write_dynamic_tail(self.as_bytes(), writer)
1736 }
1737
1738 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1739 hasher.update(b"string")
1740 }
1741}
1742
1743impl<const MIN: usize, const CAP: usize> EvmCdDeserialise for EvmCdString<MIN, CAP> {
1744 type Buffer = EvmCdBuffer<([u8; 64], [u8; CAP], [u8; 31])>;
1745
1746 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
1747 if MIN > CAP {
1748 return Err(invalid_data());
1749 }
1750 let (bytes, len) = read_dynamic_bytes::<CAP, _>(reader)?;
1751 if len < MIN || core::str::from_utf8(&bytes[..len]).is_err() {
1752 return Err(invalid_data());
1753 }
1754 Ok(Self { len, bytes })
1755 }
1756
1757 fn is_abi_dynamic() -> bool {
1758 true
1759 }
1760
1761 fn abi_tail_size(&self) -> usize {
1762 dynamic_tail_size(self.len)
1763 }
1764
1765 fn deserialise_abi_head<R: Read>(reader: &mut R) -> Result<EvmCdHead<Self>, Error> {
1766 Ok(EvmCdHead::Offset(read_usize_word(reader)?))
1767 }
1768
1769 fn deserialise_abi_finish<R: Read>(
1770 head: EvmCdHead<Self>,
1771 expected_tail_offset: usize,
1772 reader: &mut R,
1773 ) -> Result<Self, Error> {
1774 match head {
1775 EvmCdHead::Offset(offset) if offset == expected_tail_offset => {
1776 if MIN > CAP {
1777 return Err(invalid_data());
1778 }
1779 let (bytes, len) = read_dynamic_tail::<CAP, _>(reader)?;
1780 if len < MIN || core::str::from_utf8(&bytes[..len]).is_err() {
1781 return Err(invalid_data());
1782 }
1783 Ok(Self { len, bytes })
1784 }
1785 _ => Err(invalid_data()),
1786 }
1787 }
1788
1789 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1790 hasher.update(b"string")
1791 }
1792}
1793
1794#[cfg(feature = "alloc")]
1795impl<const MIN: usize, const CAP: usize> From<EvmCdString<MIN, CAP>> for String {
1796 fn from(value: EvmCdString<MIN, CAP>) -> Self {
1797 String::from(value.as_str())
1798 }
1799}
1800
1801#[cfg(feature = "alloc")]
1802fn vec_is_bytes<T: 'static>() -> bool {
1803 core::any::TypeId::of::<T>() == core::any::TypeId::of::<u8>()
1804}
1805
1806#[cfg(feature = "alloc")]
1807fn vec_as_bytes<T: 'static>(values: &[T]) -> &[u8] {
1808 debug_assert!(vec_is_bytes::<T>());
1809 unsafe { core::slice::from_raw_parts(values.as_ptr().cast::<u8>(), values.len()) }
1811}
1812
1813#[cfg(feature = "alloc")]
1814impl<T> EvmCdSerialise for Vec<T>
1815where
1816 T: EvmCdSerialise + 'static,
1817{
1818 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1819 U::from_u32(32).serialise_value(writer)?;
1820 self.serialise_abi_tail(writer)
1821 }
1822
1823 fn is_abi_dynamic() -> bool {
1824 true
1825 }
1826
1827 fn abi_tail_size(&self) -> usize {
1828 if vec_is_bytes::<T>() {
1829 dynamic_tail_size(self.len())
1830 } else {
1831 self.len()
1832 .saturating_mul(T::abi_head_size())
1833 .saturating_add(32)
1834 .saturating_add(self.iter().fold(0usize, |size, value| {
1835 size.saturating_add(value.abi_tail_size())
1836 }))
1837 }
1838 }
1839
1840 fn serialise_abi_head<W: Write>(
1841 &self,
1842 tail_offset: usize,
1843 writer: &mut W,
1844 ) -> Result<(), Error> {
1845 U::from_usize(tail_offset).serialise_value(writer)
1846 }
1847
1848 fn serialise_abi_tail<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1849 if vec_is_bytes::<T>() {
1850 return write_dynamic_tail(vec_as_bytes(self), writer);
1851 }
1852
1853 U::from_usize(self.len()).serialise_value(writer)?;
1854 let mut tail_offset = self
1855 .len()
1856 .checked_mul(T::abi_head_size())
1857 .ok_or_else(invalid_data)?;
1858 for value in self {
1859 value.serialise_abi_head(tail_offset, writer)?;
1860 tail_offset = tail_offset
1861 .checked_add(value.abi_tail_size())
1862 .ok_or_else(invalid_data)?;
1863 }
1864 for value in self {
1865 value.serialise_abi_tail(writer)?;
1866 }
1867 Ok(())
1868 }
1869
1870 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1871 if vec_is_bytes::<T>() {
1872 hasher.update(b"bytes")
1873 } else {
1874 T::append_abi_type(hasher).update(b"[]")
1875 }
1876 }
1877}
1878
1879#[cfg(feature = "alloc")]
1880const MAX_ALLOC_DESERIALISE_LEN: usize = 16 * 1024 * 1024;
1881
1882#[cfg(feature = "alloc")]
1883fn read_vec_bytes_tail<R: Read>(reader: &mut R) -> Result<Vec<u8>, Error> {
1884 let len = read_usize_word(reader)?;
1885 if len > MAX_ALLOC_DESERIALISE_LEN {
1886 return Err(invalid_data());
1887 }
1888 let mut out = Vec::new();
1889 out.try_reserve_exact(len).map_err(|_| invalid_data())?;
1890 out.resize(len, 0);
1891 reader.read_exact(&mut out)?;
1892 let padding = (32 - len % 32) % 32;
1893 let mut padding_bytes = [0u8; 31];
1894 reader.read_exact(&mut padding_bytes[..padding])?;
1895 if padding_bytes[..padding].iter().any(|byte| *byte != 0) {
1896 return Err(invalid_data());
1897 }
1898 Ok(out)
1899}
1900
1901#[cfg(feature = "alloc")]
1902fn bytes_into_vec<T: 'static>(bytes: Vec<u8>) -> Vec<T> {
1903 debug_assert!(vec_is_bytes::<T>());
1904 let mut bytes = core::mem::ManuallyDrop::new(bytes);
1905 unsafe {
1907 Vec::from_raw_parts(
1908 bytes.as_mut_ptr().cast::<T>(),
1909 bytes.len(),
1910 bytes.capacity(),
1911 )
1912 }
1913}
1914
1915#[cfg(feature = "alloc")]
1916fn validate_vec_array_len<T: EvmCdDeserialise>(len: usize) -> Result<(), Error> {
1917 let head_bytes = len
1918 .checked_mul(T::abi_head_size())
1919 .ok_or_else(invalid_data)?;
1920 let value_bytes = len
1921 .checked_mul(core::mem::size_of::<T>())
1922 .ok_or_else(invalid_data)?;
1923 let offset_bytes = if T::is_abi_dynamic() {
1924 len.checked_mul(core::mem::size_of::<usize>())
1925 .ok_or_else(invalid_data)?
1926 } else {
1927 0
1928 };
1929 if head_bytes > MAX_ALLOC_DESERIALISE_LEN
1930 || value_bytes > MAX_ALLOC_DESERIALISE_LEN
1931 || offset_bytes > MAX_ALLOC_DESERIALISE_LEN
1932 {
1933 return Err(invalid_data());
1934 }
1935 Ok(())
1936}
1937
1938#[cfg(feature = "alloc")]
1939fn read_vec_array_tail<T, R>(reader: &mut R) -> Result<Vec<T>, Error>
1940where
1941 T: EvmCdDeserialise + 'static,
1942 R: Read,
1943{
1944 let len = read_usize_word(reader)?;
1945 validate_vec_array_len::<T>(len)?;
1946
1947 let mut out = Vec::new();
1948 out.try_reserve_exact(len).map_err(|_| invalid_data())?;
1949 if T::is_abi_dynamic() {
1950 let mut offsets = Vec::new();
1951 offsets.try_reserve_exact(len).map_err(|_| invalid_data())?;
1952 for _ in 0..len {
1953 match T::deserialise_abi_head(reader)? {
1954 EvmCdHead::Offset(offset) => offsets.push(offset),
1955 EvmCdHead::Value(_) => return Err(invalid_data()),
1956 }
1957 }
1958 let mut expected_tail_offset = len
1959 .checked_mul(T::abi_head_size())
1960 .ok_or_else(invalid_data)?;
1961 for offset in offsets {
1962 let value =
1963 T::deserialise_abi_finish(EvmCdHead::Offset(offset), expected_tail_offset, reader)?;
1964 expected_tail_offset = expected_tail_offset
1965 .checked_add(value.abi_tail_size())
1966 .ok_or_else(invalid_data)?;
1967 out.push(value);
1968 }
1969 } else {
1970 for _ in 0..len {
1971 let head = T::deserialise_abi_head(reader)?;
1972 out.push(T::deserialise_abi_finish(head, 0, reader)?);
1973 }
1974 }
1975 Ok(out)
1976}
1977
1978#[cfg(feature = "alloc")]
1979fn read_vec_tail<T, R>(reader: &mut R) -> Result<Vec<T>, Error>
1980where
1981 T: EvmCdDeserialise + 'static,
1982 R: Read,
1983{
1984 if vec_is_bytes::<T>() {
1985 read_vec_bytes_tail(reader).map(bytes_into_vec)
1986 } else {
1987 read_vec_array_tail(reader)
1988 }
1989}
1990
1991#[cfg(feature = "alloc")]
1992impl<T> EvmCdDeserialise for Vec<T>
1993where
1994 T: EvmCdDeserialise + 'static,
1995{
1996 type Buffer = EvmCdDynamicBuffer<()>;
1997
1998 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
1999 if read_usize_word(reader)? != 32 {
2000 return Err(invalid_data());
2001 }
2002 read_vec_tail(reader)
2003 }
2004
2005 fn is_abi_dynamic() -> bool {
2006 true
2007 }
2008
2009 fn abi_tail_size(&self) -> usize {
2010 if vec_is_bytes::<T>() {
2011 dynamic_tail_size(self.len())
2012 } else {
2013 self.len()
2014 .saturating_mul(T::abi_head_size())
2015 .saturating_add(32)
2016 .saturating_add(self.iter().fold(0usize, |size, value| {
2017 size.saturating_add(value.abi_tail_size())
2018 }))
2019 }
2020 }
2021
2022 fn deserialise_abi_head<R: Read>(reader: &mut R) -> Result<EvmCdHead<Self>, Error> {
2023 Ok(EvmCdHead::Offset(read_usize_word(reader)?))
2024 }
2025
2026 fn deserialise_abi_finish<R: Read>(
2027 head: EvmCdHead<Self>,
2028 expected_tail_offset: usize,
2029 reader: &mut R,
2030 ) -> Result<Self, Error> {
2031 match head {
2032 EvmCdHead::Offset(offset) if offset == expected_tail_offset => read_vec_tail(reader),
2033 _ => Err(invalid_data()),
2034 }
2035 }
2036
2037 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
2038 if vec_is_bytes::<T>() {
2039 hasher.update(b"bytes")
2040 } else {
2041 T::append_abi_type(hasher).update(b"[]")
2042 }
2043 }
2044}
2045
2046#[cfg(all(test, not(feature = "std")))]
2047mod tests {
2048 use super::{EvmCdDeserialise, EvmCdSerialise};
2049
2050 #[derive(
2051 Debug, PartialEq, Eq, bobcat_cd_derive::EvmCdSerialise, bobcat_cd_derive::EvmCdDeserialise,
2052 )]
2053 struct SliceValue {
2054 small: u8,
2055 large: u32,
2056 }
2057
2058 #[test]
2059 fn mutable_slice_is_a_serialisation_writer_and_deserialisation_reader() {
2060 let value = SliceValue {
2061 small: 7,
2062 large: 0x1234_5678,
2063 };
2064 let mut storage = [0u8; 64];
2065
2066 let mut writer = storage.as_mut_slice();
2067 value.serialise(&mut writer).unwrap();
2068 assert!(writer.is_empty());
2069
2070 let mut reader = storage.as_mut_slice();
2071 assert_eq!(SliceValue::deserialise_reader(&mut reader).unwrap(), value);
2072 assert!(reader.is_empty());
2073 }
2074}