1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#[macro_use] extern crate proc_macro_hack; #[inline(always)] fn is_hex_char(c: &char) -> bool { match *c { '0'...'9' | 'a'...'f' | 'A'...'F' => true, _ => false, } } #[inline(always)] fn is_format_char(c: &char) -> bool { match *c { ' ' | '\r' | '\n' | '\t' => true, _ => false, } } proc_macro_expr_impl! { pub fn hex_impl(input: &str) -> String { let bytes = input.as_bytes(); let n = bytes.len(); if bytes[0] != b'"' || bytes[n-1] != b'"' { return "compile_error!(\"expected string literal\")".to_string(); } let input = &input[1..n-1]; for (i, c) in input.chars().enumerate() { if !(is_hex_char(&c) || is_format_char(&c)) { return format!("compile_error!(\"\ invalid character (position {}): {:?}\")", i + 1, c); } }; let n = input.chars().filter(is_hex_char).count() / 2; let mut s = String::with_capacity(2 + 7*n); s.push('['); let mut iter = input.chars().filter(is_hex_char); while let Some(c1) = iter.next() { if let Some(c2) = iter.next() { s += "0x"; s.push(c1); s.push(c2); s += "u8,"; } else { return "compile_error!(\"\ expected even number of hex characters\")".to_string(); } } s.push(']'); s } }