moverox_types/
lib.rs

1#![cfg_attr(all(doc, not(doctest)), feature(doc_auto_cfg))]
2
3//! Building blocks for oxidized Move types.
4
5mod 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
16/// Contruct an [`Address`] from hex bytes at compile time.
17///
18/// # Example
19/// ```
20/// use moverox_types::{Address, const_address};
21///
22/// const FRAMEWORK: Address = const_address(b"0x2");
23/// ```
24pub 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}