hex_macro/lib.rs
1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, LitStr};
4
5/// Decodes a hex string into a byte array at compile time
6///
7/// # Examples
8///
9/// ```rust
10/// use hex_macro::hex;
11/// const DATA: [u8; 11] = hex!("48656c6c6f20776f726c64");
12/// assert_eq!(DATA, *b"Hello world");
13/// ```
14///
15/// ```rust
16/// use hex_macro::hex;
17/// // With a '0x' prefix
18/// const DATA: [u8; 11] = hex!("0x48656c6c6f20776f726c64");
19/// assert_eq!(DATA, *b"Hello world");
20/// ```
21///
22/// ```compile_fail
23/// use hex_macro::hex;
24/// const DATA: [u8; 10] = hex!("48656c6c6f20776f726c64"); // Wrong length byte array
25/// ```
26///
27/// ```compile_fail
28/// hex!("notvalidhexstring!"); // not a valid hex string
29/// ```
30#[proc_macro]
31pub fn hex(input: TokenStream) -> TokenStream {
32 let input = parse_macro_input!(input as LitStr).value();
33
34 // Trim '0x' from start
35 let input = input.trim_start_matches("0x");
36
37 match hex::decode(input) {
38 Ok(decoded) => {
39 let len = decoded.len();
40 let byte_array = quote! {
41 {
42 const DATA: [u8; #len] = [#(#decoded),*];
43 DATA
44 }
45 };
46 byte_array.into()
47 }
48 Err(_) => panic!("Invalid hex string"),
49 }
50}