diff --git a/phf/tests/test.rs b/phf/tests/test.rs index 19eadf6f..8341b677 100644 --- a/phf/tests/test.rs +++ b/phf/tests/test.rs @@ -143,6 +143,24 @@ mod map { }) ) + #[test] + fn test_array_vals() { + static MAP: phf::Map<&'static str, [u8, ..3]> = phf_map!( + "a" => [0u8, 1, 2], + ); + assert_eq!(Some(&[0u8, 1, 2]), MAP.get(&("a"))); + } + + #[test] + fn test_array_keys() { + static MAP: phf::Map<[u8, ..2], int> = phf_map!( + [0u8, 1] => 0, + [2, 3u8] => 1, + [4, 5] => 2, + ); + assert_eq!(Some(&0), MAP.get(&[0u8, 1u8])); + } + #[test] fn test_binary_keys() { test_key_type!(&'static [u8], b"hello" => 0, b"world" => 1); diff --git a/phf_mac/src/lib.rs b/phf_mac/src/lib.rs index 7f975240..63619694 100644 --- a/phf_mac/src/lib.rs +++ b/phf_mac/src/lib.rs @@ -13,8 +13,8 @@ extern crate phf_shared; use std::collections::HashMap; use std::collections::hash_map::{Occupied, Vacant}; -use syntax::ast::{mod, TokenTree, LitStr, LitBinary, LitByte, LitChar, Expr, ExprLit}; -use syntax::codemap::Span; +use syntax::ast::{mod, TokenTree, LitStr, LitBinary, LitByte, LitChar, Expr, ExprLit, ExprVec}; +use syntax::codemap::{Span, Spanned}; use syntax::ext::base::{DummyResult, ExtCtxt, MacResult}; @@ -195,6 +195,24 @@ fn parse_key(cx: &mut ExtCtxt, e: &Expr) -> Option { } } } + ExprVec(ref v) => { + let bytes: Vec> = v.iter().map(|expr| + if let ExprLit(ref p) = expr.node { + match **p { + Spanned {node: ast::LitInt(val, ast::UnsignedIntLit(ast::UintTy::TyU8)), ..} if val < 256 => Some(val as u8), + Spanned {node: ast::LitInt(val, ast::UnsuffixedIntLit(ast::Plus)), ..} if val < 256 => Some(val as u8), + _ => None, + } + } else { + None + }).collect(); + if bytes.iter().all(|x| x.is_some()) { + Some(Key::Binary(std::rc::Rc::new(bytes.iter().map(|x| x.unwrap()).collect()))) + } else { + cx.span_err(e.span, "not all elements of an expected u8 array literal were u8 literals"); + None + } + } _ => { cx.span_err(e.span, "expected a literal"); None diff --git a/phf_shared/src/lib.rs b/phf_shared/src/lib.rs index 8179f8e6..e00e61fd 100644 --- a/phf_shared/src/lib.rs +++ b/phf_shared/src/lib.rs @@ -76,3 +76,47 @@ sip_impl!(u64) sip_impl!(i64) sip_impl!(char) sip_impl!(bool) + +macro_rules! array_impl( + ($t:ty, $n:expr) => ( + impl PhfHash for [$t, ..$n] { + #[inline] + fn phf_hash(&self, seed: u64) -> (u32, u32, u32) { + split(xxhash::oneshot(self, seed)) + } + } + ) +) + +array_impl!(u8, 1) +array_impl!(u8, 2) +array_impl!(u8, 3) +array_impl!(u8, 4) +array_impl!(u8, 5) +array_impl!(u8, 6) +array_impl!(u8, 7) +array_impl!(u8, 8) +array_impl!(u8, 9) +array_impl!(u8, 10) +array_impl!(u8, 11) +array_impl!(u8, 12) +array_impl!(u8, 13) +array_impl!(u8, 14) +array_impl!(u8, 15) +array_impl!(u8, 16) +array_impl!(u8, 17) +array_impl!(u8, 18) +array_impl!(u8, 19) +array_impl!(u8, 20) +array_impl!(u8, 21) +array_impl!(u8, 22) +array_impl!(u8, 23) +array_impl!(u8, 24) +array_impl!(u8, 25) +array_impl!(u8, 26) +array_impl!(u8, 27) +array_impl!(u8, 28) +array_impl!(u8, 29) +array_impl!(u8, 30) +array_impl!(u8, 31) +array_impl!(u8, 32)