xrpl/core/binarycodec/
utils.rs1use super::definitions::load_definition_map;
4use super::definitions::DefinitionHandler;
5use super::definitions::FieldHeader;
6use super::definitions::CODE_MAX_VALUE;
7use super::definitions::CODE_MIN_VALUE;
8use crate::core::binarycodec::exceptions::XRPLBinaryCodecException;
9use crate::core::exceptions::XRPLCoreResult;
10use alloc::vec;
11use alloc::vec::Vec;
12
13pub const MAX_SINGLE_BYTE_LENGTH: usize = 192;
16pub const MAX_DOUBLE_BYTE_LENGTH: usize = 12481;
19pub const MAX_SECOND_BYTE_VALUE: usize = 240;
22pub const MAX_DOUBLE_BYTE_VALUE: usize = 65536;
25pub const MAX_LENGTH_VALUE: usize = 918744;
28pub const MAX_BYTE_VALUE: usize = 256;
31
32fn _encode_field_id(field_header: &FieldHeader) -> XRPLCoreResult<Vec<u8>> {
34 let type_code = field_header.type_code;
35 let field_code = field_header.field_code;
36 let range = CODE_MIN_VALUE..CODE_MAX_VALUE;
37
38 if !range.contains(&field_code) {
39 Err(XRPLBinaryCodecException::UnexpectedFieldCodeRange {
40 min: CODE_MIN_VALUE as usize,
41 max: CODE_MAX_VALUE as usize,
42 }
43 .into())
44 } else if !range.contains(&type_code) {
45 Err(XRPLBinaryCodecException::UnexpectedTypeCodeRange {
46 min: CODE_MIN_VALUE as usize,
47 max: CODE_MAX_VALUE as usize,
48 }
49 .into())
50 } else if type_code < 16 && field_code < 16 {
51 let combined_code = (type_code << 4) | field_code;
54 Ok([combined_code as u8].to_vec())
55 } else if type_code >= 16 && field_code < 16 {
56 let mut result = vec![];
60 let byte1 = [field_code as u8];
61 let byte2 = [type_code as u8];
62
63 result.extend_from_slice(&byte1);
64 result.extend_from_slice(&byte2);
65
66 Ok(result)
67 } else if type_code < 16 && field_code >= 16 {
68 let mut result = vec![];
72 let byte1 = [(type_code << 4) as u8];
73 let byte2 = [field_code as u8];
74
75 result.extend_from_slice(&byte1);
76 result.extend_from_slice(&byte2);
77
78 Ok(result)
79 } else {
80 let mut result = vec![];
85 let byte2 = [type_code as u8];
86 let byte3 = [field_code as u8];
87
88 result.extend_from_slice(&[0]);
89 result.extend_from_slice(&byte2);
90 result.extend_from_slice(&byte3);
91
92 Ok(result)
93 }
94}
95
96fn _decode_field_id(field_id: &str) -> XRPLCoreResult<FieldHeader> {
98 let bytes = hex::decode(field_id)?;
99
100 match bytes.len() {
101 1 => {
102 let type_code = (bytes[0] >> 4) as i16;
103 let field_code = (bytes[0] & 0x0F) as i16;
104
105 Ok(FieldHeader {
106 type_code,
107 field_code,
108 })
109 }
110 2 => {
111 let first_byte = bytes[0];
112 let second_byte = bytes[1];
113 let first_byte_high_bits = first_byte >> 4;
114 let first_byte_low_bits = first_byte & 0x0F;
115
116 if first_byte_high_bits == 0 {
117 let type_code = second_byte as i16;
120 let field_code = first_byte_low_bits as i16;
121
122 Ok(FieldHeader {
123 type_code,
124 field_code,
125 })
126 } else {
127 let type_code = first_byte_high_bits as i16;
130 let field_code = second_byte as i16;
131
132 Ok(FieldHeader {
133 type_code,
134 field_code,
135 })
136 }
137 }
138 3 => {
139 let type_code = bytes[1] as i16;
140 let field_code = bytes[2] as i16;
141
142 Ok(FieldHeader {
143 type_code,
144 field_code,
145 })
146 }
147 _ => Err(XRPLBinaryCodecException::UnexpectedFieldIdByteRange { min: 1, max: 3 }.into()),
148 }
149}
150
151pub fn encode_field_name(field_name: &str) -> XRPLCoreResult<Vec<u8>> {
184 let definitions = load_definition_map();
185 let field_header = definitions.get_field_header_from_name(field_name);
186 if let Some(header) = field_header {
187 _encode_field_id(&header)
188 } else {
189 Err(XRPLBinaryCodecException::UnknownFieldName.into())
190 }
191}
192
193pub fn decode_field_name(field_id: &str) -> XRPLCoreResult<&str> {
224 let definitions = load_definition_map();
225 let field_header = _decode_field_id(field_id)?;
226 let field_name = definitions.get_field_name_from_header(&field_header);
227
228 if let Some(name) = field_name {
229 Ok(name)
230 } else {
231 Err(XRPLBinaryCodecException::UnknownFieldName.into())
232 }
233}
234
235#[cfg(test)]
236mod test {
237 use super::*;
238 use crate::core::binarycodec::test_cases::load_field_tests;
239
240 #[test]
241 fn test_encode_field_name() {
242 for test in load_field_tests() {
243 let result = hex::encode_upper(encode_field_name(&test.name).expect(""));
244 assert_eq!(test.expected_hex, result)
245 }
246 }
247
248 #[test]
249 fn test_decode_field_name() {
250 for test in load_field_tests() {
251 assert_eq!(
252 decode_field_name(&test.expected_hex),
253 Ok(test.name.as_ref())
254 )
255 }
256 }
257}