xrpl_common_stdlib/fields/
decoder.rs1use crate::host;
11use crate::types::decode_error::DecodeError;
12
13pub trait FieldDecoder: Sized {
15 type Buffer: AsMut<[u8]> + AsRef<[u8]>;
21
22 fn empty_buffer() -> Self::Buffer;
24
25 fn decode(buf: Self::Buffer, bytes_written: usize) -> Result<Self, DecodeError>;
39}
40
41pub trait FromCurrentTx: FieldDecoder {}
43
44pub trait FromLedger: FieldDecoder {}
46
47#[inline]
54pub(crate) fn decode_host_result<T: FieldDecoder>(buf: T::Buffer, n: i32) -> host::Result<T> {
55 if n < 0 {
56 return host::Result::Err(host::Error::from_code(n));
57 }
58 let n = n as usize;
59 if n > buf.as_ref().len() {
60 return host::Result::Err(host::Error::PointerOutOfBounds);
63 }
64 match T::decode(buf, n) {
65 Ok(value) => host::Result::Ok(value),
66 Err(_) => host::Result::Err(host::Error::InvalidDecoding),
67 }
68}
69
70#[inline]
77pub(crate) fn decode_exact<T, Buf>(buf: Buf, bytes_written: usize) -> Result<T, DecodeError>
78where
79 Buf: AsRef<[u8]>,
80 T: From<Buf>,
81{
82 if bytes_written != buf.as_ref().len() {
83 return Err(DecodeError);
84 }
85 Ok(T::from(buf))
86}
87
88impl FieldDecoder for u8 {
89 type Buffer = [u8; 1];
90
91 #[inline]
92 fn empty_buffer() -> Self::Buffer {
93 [0u8; 1]
94 }
95
96 #[inline]
97 fn decode(buf: Self::Buffer, bytes_written: usize) -> Result<Self, DecodeError> {
98 if bytes_written != buf.len() {
99 return Err(DecodeError);
100 }
101 Ok(u8::from_le_bytes(buf))
102 }
103}
104
105impl FromCurrentTx for u8 {}
106impl FromLedger for u8 {}
107
108impl FieldDecoder for u16 {
109 type Buffer = [u8; 2];
110
111 #[inline]
112 fn empty_buffer() -> Self::Buffer {
113 [0u8; 2]
114 }
115
116 #[inline]
117 fn decode(buf: Self::Buffer, bytes_written: usize) -> Result<Self, DecodeError> {
118 if bytes_written != buf.len() {
119 return Err(DecodeError);
120 }
121 Ok(u16::from_le_bytes(buf))
122 }
123}
124
125impl FromCurrentTx for u16 {}
126impl FromLedger for u16 {}
127
128impl FieldDecoder for u32 {
129 type Buffer = [u8; 4];
130
131 #[inline]
132 fn empty_buffer() -> Self::Buffer {
133 [0u8; 4]
134 }
135
136 #[inline]
137 fn decode(buf: Self::Buffer, bytes_written: usize) -> Result<Self, DecodeError> {
138 if bytes_written != buf.len() {
139 return Err(DecodeError);
140 }
141 Ok(u32::from_le_bytes(buf))
142 }
143}
144
145impl FromCurrentTx for u32 {}
146impl FromLedger for u32 {}
147
148impl FieldDecoder for u64 {
149 type Buffer = [u8; 8];
150
151 #[inline]
152 fn empty_buffer() -> Self::Buffer {
153 [0u8; 8]
154 }
155
156 #[inline]
157 fn decode(buf: Self::Buffer, bytes_written: usize) -> Result<Self, DecodeError> {
158 if bytes_written != buf.len() {
159 return Err(DecodeError);
160 }
161 Ok(u64::from_le_bytes(buf))
162 }
163}
164
165impl FromCurrentTx for u64 {}
166impl FromLedger for u64 {}
167
168impl FieldDecoder for i32 {
169 type Buffer = [u8; 4];
170
171 #[inline]
172 fn empty_buffer() -> Self::Buffer {
173 [0u8; 4]
174 }
175
176 #[inline]
177 fn decode(buf: Self::Buffer, bytes_written: usize) -> Result<Self, DecodeError> {
178 if bytes_written != buf.len() {
179 return Err(DecodeError);
180 }
181 Ok(i32::from_le_bytes(buf))
182 }
183}
184
185impl FromCurrentTx for i32 {}
186impl FromLedger for i32 {}
187
188#[cfg(test)]
189mod tests {
190 use super::*;
191
192 #[derive(Debug, PartialEq, Eq)]
193 struct TxOnly(u8);
194
195 impl FieldDecoder for TxOnly {
196 type Buffer = [u8; 1];
197
198 fn empty_buffer() -> Self::Buffer {
199 [0u8; 1]
200 }
201
202 fn decode(buf: Self::Buffer, bytes_written: usize) -> Result<Self, DecodeError> {
203 if bytes_written == 0 {
204 return Err(DecodeError);
205 }
206 Ok(TxOnly(buf[0]))
207 }
208 }
209 impl FromCurrentTx for TxOnly {}
210
211 #[derive(Debug, PartialEq, Eq)]
212 struct ObjOnly(u8);
213
214 impl FieldDecoder for ObjOnly {
215 type Buffer = [u8; 1];
216
217 fn empty_buffer() -> Self::Buffer {
218 [0u8; 1]
219 }
220
221 fn decode(buf: Self::Buffer, bytes_written: usize) -> Result<Self, DecodeError> {
222 if bytes_written == 0 {
223 return Err(DecodeError);
224 }
225 Ok(ObjOnly(buf[0]))
226 }
227 }
228 impl FromLedger for ObjOnly {}
229
230 #[derive(Debug, PartialEq, Eq)]
231 struct TxAndObj(u8);
232
233 impl FieldDecoder for TxAndObj {
234 type Buffer = [u8; 1];
235
236 fn empty_buffer() -> Self::Buffer {
237 [0u8; 1]
238 }
239
240 fn decode(buf: Self::Buffer, bytes_written: usize) -> Result<Self, DecodeError> {
241 if bytes_written == 0 {
242 return Err(DecodeError);
243 }
244 Ok(TxAndObj(buf[0]))
245 }
246 }
247 impl FromCurrentTx for TxAndObj {}
248 impl FromLedger for TxAndObj {}
249
250 fn assert_from_current_tx<T: FromCurrentTx>() {}
255 fn assert_from_ledger<T: FromLedger>() {}
256
257 #[test]
258 fn tx_only_implements_from_current_tx_only() {
259 assert_from_current_tx::<TxOnly>();
260 }
261
262 #[test]
263 fn obj_only_implements_from_ledger_only() {
264 assert_from_ledger::<ObjOnly>();
265 }
266
267 #[test]
268 fn tx_and_obj_implements_both() {
269 assert_from_current_tx::<TxAndObj>();
270 assert_from_ledger::<TxAndObj>();
271 }
272
273 #[test]
274 fn decode_returns_value_on_success() {
275 assert_eq!(TxOnly::decode([42], 1), Ok(TxOnly(42)));
276 }
277
278 #[test]
279 fn decode_returns_error_on_empty_input() {
280 assert_eq!(TxOnly::decode([0], 0), Err(DecodeError));
281 }
282
283 #[test]
284 fn empty_buffer_has_expected_length() {
285 let mut buffer = <TxOnly as FieldDecoder>::empty_buffer();
286 assert_eq!(buffer.as_mut().len(), 1);
287 }
288}