eth_valkyoth_codec/rlp/
traits.rs1use core::fmt;
2
3use crate::{DecodeError, DecodeLimits, checked_len_add};
4
5use super::{
6 RlpInteger, RlpItem, decode_rlp_u64, decode_rlp_u128, encode_rlp_integer, encode_rlp_scalar,
7 encoded_rlp_integer_len, encoded_rlp_scalar_len,
8};
9
10pub trait RlpEncode {
20 type Error;
22
23 fn encoded_rlp_len(&self) -> Result<usize, Self::Error>;
25
26 fn encode_rlp(&self, output: &mut [u8]) -> Result<usize, Self::Error>;
30}
31
32pub trait RlpDecode: Sized {
34 type Error;
36
37 fn decode_rlp(input: &[u8], limits: DecodeLimits) -> Result<Self, Self::Error>;
39
40 fn decode_rlp_item(item: RlpItem<'_>) -> Result<Self, Self::Error>;
42}
43
44#[non_exhaustive]
46#[derive(Clone, Copy, Debug, Eq, PartialEq)]
47pub enum RlpDeriveError {
48 Decode(DecodeError),
50 Field,
52 WrongFieldCount {
54 expected: usize,
56 found: usize,
58 },
59}
60
61impl From<DecodeError> for RlpDeriveError {
62 fn from(error: DecodeError) -> Self {
63 Self::Decode(error)
64 }
65}
66
67impl fmt::Display for RlpDeriveError {
68 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
69 match self {
70 Self::Decode(error) => write!(formatter, "RLP codec error: {error}"),
71 Self::Field => formatter.write_str("RLP field codec error"),
72 Self::WrongFieldCount { expected, found } => write!(
73 formatter,
74 "RLP list field count mismatch: expected {expected}, found {found}"
75 ),
76 }
77 }
78}
79
80#[cfg(feature = "std")]
81impl std::error::Error for RlpDeriveError {
82 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
83 match self {
84 Self::Decode(error) => Some(error),
85 Self::Field | Self::WrongFieldCount { .. } => None,
86 }
87 }
88}
89
90impl From<core::convert::Infallible> for RlpDeriveError {
91 fn from(error: core::convert::Infallible) -> Self {
92 match error {}
93 }
94}
95
96impl RlpEncode for u64 {
97 type Error = DecodeError;
98
99 fn encoded_rlp_len(&self) -> Result<usize, Self::Error> {
100 let bytes = self.to_be_bytes();
101 encoded_rlp_integer_len(trim_payload(&bytes))
102 }
103
104 fn encode_rlp(&self, output: &mut [u8]) -> Result<usize, Self::Error> {
105 let bytes = self.to_be_bytes();
106 encode_rlp_integer(trim_payload(&bytes), output)
107 }
108}
109
110impl RlpDecode for u64 {
111 type Error = DecodeError;
112
113 fn decode_rlp(input: &[u8], limits: DecodeLimits) -> Result<Self, Self::Error> {
114 decode_rlp_u64(input, limits)
115 }
116
117 fn decode_rlp_item(item: RlpItem<'_>) -> Result<Self, Self::Error> {
118 let scalar = item.as_scalar().ok_or(DecodeError::UnexpectedList)?;
119 RlpInteger::try_from_scalar(scalar)?.to_u64()
120 }
121}
122
123impl RlpEncode for u128 {
124 type Error = DecodeError;
125
126 fn encoded_rlp_len(&self) -> Result<usize, Self::Error> {
127 let bytes = self.to_be_bytes();
128 encoded_rlp_integer_len(trim_payload(&bytes))
129 }
130
131 fn encode_rlp(&self, output: &mut [u8]) -> Result<usize, Self::Error> {
132 let bytes = self.to_be_bytes();
133 encode_rlp_integer(trim_payload(&bytes), output)
134 }
135}
136
137impl RlpDecode for u128 {
138 type Error = DecodeError;
139
140 fn decode_rlp(input: &[u8], limits: DecodeLimits) -> Result<Self, Self::Error> {
141 decode_rlp_u128(input, limits)
142 }
143
144 fn decode_rlp_item(item: RlpItem<'_>) -> Result<Self, Self::Error> {
145 let scalar = item.as_scalar().ok_or(DecodeError::UnexpectedList)?;
146 RlpInteger::try_from_scalar(scalar)?.to_u128()
147 }
148}
149
150impl<const N: usize> RlpEncode for [u8; N] {
151 type Error = DecodeError;
152
153 fn encoded_rlp_len(&self) -> Result<usize, Self::Error> {
154 encoded_rlp_scalar_len(self)
155 }
156
157 fn encode_rlp(&self, output: &mut [u8]) -> Result<usize, Self::Error> {
158 encode_rlp_scalar(self, output)
159 }
160}
161
162impl<const N: usize> RlpDecode for [u8; N] {
163 type Error = DecodeError;
164
165 fn decode_rlp(input: &[u8], limits: DecodeLimits) -> Result<Self, Self::Error> {
166 let scalar = super::decode_rlp_scalar(input, limits)?;
167 scalar
168 .payload()
169 .try_into()
170 .map_err(|_| DecodeError::Malformed)
171 }
172
173 fn decode_rlp_item(item: RlpItem<'_>) -> Result<Self, Self::Error> {
174 let scalar = item.as_scalar().ok_or(DecodeError::UnexpectedList)?;
175 scalar
176 .payload()
177 .try_into()
178 .map_err(|_| DecodeError::Malformed)
179 }
180}
181
182fn trim_payload<const N: usize>(bytes: &[u8; N]) -> &[u8] {
183 let start = bytes.iter().position(|byte| *byte != 0).unwrap_or(N);
184 bytes.get(start..).unwrap_or(&[])
185}
186
187pub fn checked_encoded_len_add(left: usize, right: usize) -> Result<usize, RlpDeriveError> {
189 checked_len_add(left, right).map_err(Into::into)
190}