1use alloy_rlp::{Decodable, EMPTY_LIST_CODE, EMPTY_STRING_CODE, Encodable, bytes::BufMut};
2
3#[derive(Debug, Clone, PartialEq, Eq, Default)]
7pub struct NilList<T>(pub Option<T>);
8
9impl<T: Encodable> Encodable for NilList<T> {
10 fn encode(&self, out: &mut dyn BufMut) {
11 match &self.0 {
12 None => out.put_u8(EMPTY_LIST_CODE), Some(v) => v.encode(out),
14 }
15 }
16
17 fn length(&self) -> usize {
18 match &self.0 {
19 None => 1,
20 Some(v) => v.length(),
21 }
22 }
23}
24
25impl<T: Decodable> Decodable for NilList<T> {
26 fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
27 if buf.first() == Some(&EMPTY_LIST_CODE) {
28 *buf = &buf[1..];
29 return Ok(Self(None));
30 }
31 Ok(Self(Some(T::decode(buf)?)))
32 }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Default)]
39pub struct NilString<T>(pub Option<T>);
40
41impl<T: Encodable> Encodable for NilString<T> {
42 fn encode(&self, out: &mut dyn BufMut) {
43 match &self.0 {
44 None => out.put_u8(EMPTY_STRING_CODE), Some(v) => v.encode(out),
46 }
47 }
48
49 fn length(&self) -> usize {
50 match &self.0 {
51 None => 1,
52 Some(v) => v.length(),
53 }
54 }
55}
56
57impl<T: Decodable> Decodable for NilString<T> {
58 fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
59 if buf.first() == Some(&EMPTY_STRING_CODE) {
60 *buf = &buf[1..];
61 return Ok(Self(None));
62 }
63 Ok(Self(Some(T::decode(buf)?)))
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use alloy_primitives::B256;
70 use alloy_rlp::{Decodable, Encodable};
71
72 use super::*;
73
74 fn enc<T: Encodable>(v: &T) -> Vec<u8> {
75 let mut b = Vec::new();
76 v.encode(&mut b);
77 b
78 }
79
80 #[test]
81 fn nil_list_none_is_empty_list_code() {
82 let none: NilList<B256> = NilList(None);
83 assert_eq!(enc(&none), [EMPTY_LIST_CODE]);
84 assert_eq!(NilList::<B256>::decode(&mut &enc(&none)[..]).unwrap(), none);
85 }
86
87 #[test]
88 fn nil_list_some_roundtrips() {
89 let some = NilList(Some(B256::repeat_byte(0xAB)));
90 let bytes = enc(&some);
91 assert_eq!(bytes[0], 0xa0);
93 assert_eq!(&bytes[1..], B256::repeat_byte(0xAB).as_slice());
94 assert_eq!(NilList::<B256>::decode(&mut &bytes[..]).unwrap(), some);
95 }
96
97 #[test]
98 fn nil_string_none_is_empty_string_code() {
99 let none: NilString<B256> = NilString(None);
100 assert_eq!(enc(&none), [EMPTY_STRING_CODE]);
101 assert_eq!(
102 NilString::<B256>::decode(&mut &enc(&none)[..]).unwrap(),
103 none
104 );
105 }
106
107 #[test]
108 fn nil_string_some_roundtrips() {
109 let some = NilString(Some(B256::repeat_byte(0x11)));
110 assert_eq!(
111 NilString::<B256>::decode(&mut &enc(&some)[..]).unwrap(),
112 some
113 );
114 }
115}