Skip to content

Commit

Permalink
Add support for remaining literals
Browse files Browse the repository at this point in the history
  • Loading branch information
sfackler committed Jul 11, 2014
1 parent 789990e commit 55ededf
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 33 deletions.
11 changes: 3 additions & 8 deletions phf/src/lib.rs
@@ -1,4 +1,7 @@
//! Compile time optimized maps
//!
//! Keys can be string literals, byte string literals, byte literals, char
//! literals, or any of the fixed-size integral types.
#![crate_name="phf"]
#![doc(html_root_url="http://www.rust-ci.org/sfackler")]
#![crate_type="rlib"]
Expand Down Expand Up @@ -35,8 +38,6 @@ pub fn displace(f1: uint, f2: uint, d1: uint, d2: uint) -> uint {

/// An immutable map constructed at compile time.
///
/// Keys may be string, binary string, byte, or character literals.
///
/// `PhfMap`s may be created with the `phf_map` macro:
///
/// ```rust
Expand Down Expand Up @@ -216,8 +217,6 @@ impl<'a, K, V> Iterator<&'a V> for PhfMapValues<'a, K, V> {

/// An immutable set constructed at compile time.
///
/// Values may be string, binary string, byte, or character literals.
///
/// `PhfSet`s may be created with the `phf_set` macro:
///
/// ```rust
Expand Down Expand Up @@ -325,8 +324,6 @@ impl<'a, T> Iterator<&'a T> for PhfSetValues<'a, T> {

/// An order-preserving immutable map constructed at compile time.
///
/// Keys may be string, binary string, byte, or character literals.
///
/// Unlike a `PhfMap`, the order of entries in a `PhfOrderedMap` is guaranteed
/// to be the order the entries were listed in.
///
Expand Down Expand Up @@ -548,8 +545,6 @@ impl<'a, K, V> ExactSize<&'a V> for PhfOrderedMapValues<'a, K, V> {}

/// An order-preserving immutable set constructed at compile time.
///
/// Values may be string, binary string, byte, or character literals.
///
/// Unlike a `PhfSet`, the order of entries in a `PhfOrderedSet` is guaranteed
/// to be the order the entries were listed in.
///
Expand Down
79 changes: 60 additions & 19 deletions phf/src/test.rs
@@ -1,4 +1,4 @@
#![feature(phase)]
#![feature(phase, macro_rules)]

#[phase(plugin)]
extern crate phf_mac;
Expand Down Expand Up @@ -115,34 +115,75 @@ mod map {
assert_eq!(Some(&0), map.find_equiv(&"a".to_string().as_slice()));
}

macro_rules! test_key_type(
($t:ty, $($k:expr => $v:expr),+) => ({
static map: PhfMap<$t, int> = phf_map! {
$($k => $v),+
};
$(
assert_eq!(Some(&$v), map.find(&$k));
)+
})
)

#[test]
fn test_binary_keys() {
static map: PhfMap<&'static [u8], int> = phf_map! {
b"hello" => 0,
b"world" => 1
};
assert_eq!(Some(&0), map.find(&b"hello"));
assert_eq!(Some(&1), map.find(&b"world"));
test_key_type!(&'static [u8], b"hello" => 0, b"world" => 1);
}

#[test]
fn test_byte_keys() {
static map: PhfMap<u8, int> = phf_map! {
b'a' => 0,
b'b' => 1,
};
assert_eq!(Some(&0), map.find(&b'a'));
assert_eq!(Some(&1), map.find(&b'b'));
test_key_type!(u8, b'a' => 0, b'b' => 1);
}

#[test]
fn test_char_keys() {
static map: PhfMap<char, int> = phf_map! {
'a' => 0,
'b' => 1,
};
assert_eq!(Some(&0), map.find(&'a'));
assert_eq!(Some(&1), map.find(&'b'));
test_key_type!(char, 'a' => 0, 'b' => 1);
}

#[test]
fn test_i8_keys() {
test_key_type!(i8, 0i8 => 0, 1i8 => 1);
}

#[test]
fn test_i16_keys() {
test_key_type!(i16, 0i16 => 0, 1i16 => 1);
}

#[test]
fn test_i32_keys() {
test_key_type!(i32, 0i32 => 0, 1i32 => 1);
}

#[test]
fn test_i64_keys() {
test_key_type!(i64, 0i64 => 0, 1i64 => 1);
}

#[test]
fn test_u8_keys() {
test_key_type!(u8, 0u8 => 0, 1u8 => 1);
}

#[test]
fn test_u16_keys() {
test_key_type!(u16, 0u16 => 0, 1u16 => 1);
}

#[test]
fn test_u32_keys() {
test_key_type!(u32, 0u32 => 0, 1u32 => 1);
}

#[test]
fn test_u64_keys() {
test_key_type!(u64, 0u64 => 0, 1u64 => 1);
}

#[test]
fn test_bool_keys() {
test_key_type!(bool, false => 0, true => 1);
}
}

Expand Down
37 changes: 31 additions & 6 deletions phf_mac/src/lib.rs
Expand Up @@ -48,17 +48,33 @@ pub fn macro_registrar(reg: &mut Registry) {
enum Key {
KeyStr(InternedString),
KeyBinary(Rc<Vec<u8>>),
KeyByte(u8),
KeyChar(char),
KeyU8(u8),
KeyI8(i8),
KeyU16(u16),
KeyI16(i16),
KeyU32(u32),
KeyI32(i32),
KeyU64(u64),
KeyI64(i64),
KeyBool(bool),
}

impl<S: hash::Writer> Hash<S> for Key {
fn hash(&self, state: &mut S) {
match *self {
KeyStr(ref s) => s.get().hash(state),
KeyBinary(ref b) => b.hash(state),
KeyByte(b) => b.hash(state),
KeyChar(c) => c.hash(state),
KeyU8(b) => b.hash(state),
KeyI8(b) => b.hash(state),
KeyU16(b) => b.hash(state),
KeyI16(b) => b.hash(state),
KeyU32(b) => b.hash(state),
KeyI32(b) => b.hash(state),
KeyU64(b) => b.hash(state),
KeyI64(b) => b.hash(state),
KeyBool(b) => b.hash(state),
}
}
}
Expand Down Expand Up @@ -230,10 +246,19 @@ fn parse_key(cx: &mut ExtCtxt, e: &Expr) -> Option<Key> {
match e.node {
ExprLit(lit) => {
match lit.node {
LitStr(ref s, _) => Some(KeyStr(s.clone())),
LitBinary(ref b) => Some(KeyBinary(b.clone())),
LitByte(b) => Some(KeyByte(b)),
LitChar(c) => Some(KeyChar(c)),
ast::LitStr(ref s, _) => Some(KeyStr(s.clone())),
ast::LitBinary(ref b) => Some(KeyBinary(b.clone())),
ast::LitByte(b) => Some(KeyU8(b)),
ast::LitChar(c) => Some(KeyChar(c)),
ast::LitInt(i, ast::TyI8) => Some(KeyI8(i as i8)),
ast::LitInt(i, ast::TyI16) => Some(KeyI16(i as i16)),
ast::LitInt(i, ast::TyI32) => Some(KeyI32(i as i32)),
ast::LitInt(i, ast::TyI64) => Some(KeyI64(i as i64)),
ast::LitUint(i, ast::TyU8) => Some(KeyU8(i as u8)),
ast::LitUint(i, ast::TyU16) => Some(KeyU16(i as u16)),
ast::LitUint(i, ast::TyU32) => Some(KeyU32(i as u32)),
ast::LitUint(i, ast::TyU64) => Some(KeyU64(i as u64)),
ast::LitBool(b) => Some(KeyBool(b)),
_ => {
cx.span_err(e.span, "unsupported literal type");
None
Expand Down

0 comments on commit 55ededf

Please sign in to comment.