1#![cfg_attr(all(doc, not(doctest)), feature(doc_auto_cfg))]
2
3mod address;
6mod ident_str;
7mod type_tag;
8pub mod u256;
9
10pub use self::address::{Address, AddressParseError};
11pub use self::ident_str::{IdentStr, InvalidIdentifierError};
12pub use self::type_tag::{Identifier, StructTag, TypeParseError, TypeTag};
13#[doc(inline)]
14pub use self::u256::U256;
15
16pub const fn const_address(bytes: &[u8]) -> Address {
25 Address::new(self::comp_time::hex_array(bytes))
26}
27
28mod comp_time {
29 pub(super) const fn hex_array<const T: usize>(bytes: &[u8]) -> [u8; T] {
30 use const_hex::{FromHexError as E, const_decode_to_array};
31 let padded = strip_and_pad::<T>(bytes);
32 match const_decode_to_array(padded.as_flattened()) {
33 Ok(arr) => arr,
34 Err(E::OddLength) => panic!("Odd length"),
35 Err(E::InvalidStringLength) => panic!("Invalid string length"),
36 Err(E::InvalidHexCharacter { .. }) => panic!("Invalid hex character"),
37 }
38 }
39
40 const fn strip_and_pad<const T: usize>(bytes: &[u8]) -> [[u8; T]; 2] {
41 let stripped = match bytes {
42 [b'0', b'x', rest @ ..] => rest,
43 _ => bytes,
44 };
45
46 let mut matrix = [[b'0'; T], [b'0'; T]];
47 let padded = matrix.as_flattened_mut();
48 if padded.len() < stripped.len() {
49 panic!("String too long");
50 }
51 let tail_start = padded.len() - stripped.len();
52 padded.split_at_mut(tail_start).1.copy_from_slice(stripped);
53 matrix
54 }
55
56 #[test]
57 fn preprocessing() {
58 let bytes = b"0x2";
59 let processed = strip_and_pad::<32>(bytes);
60 assert_eq!(
61 processed.as_flattened(),
62 b"0000000000000000000000000000000000000000000000000000000000000002"
63 )
64 }
65}