diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/phf_macros | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/phf_macros')
10 files changed, 788 insertions, 0 deletions
diff --git a/third_party/rust/phf_macros/.cargo-checksum.json b/third_party/rust/phf_macros/.cargo-checksum.json new file mode 100644 index 0000000000..85de24adbd --- /dev/null +++ b/third_party/rust/phf_macros/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"220232fa30135dd1d2a76ea65b1eab24323522587fe8bf6064a2af5cebc1aa29","benches/bench.rs":"0daf2e53f820b4280b69cb82f694594417f32be53ead32a407817c2feb0f4874","src/lib.rs":"32bc1404d19d3382d89844fceb1d809484e2626347700eb98ffef74dcadb9829","tests/compile-fail-unicase/equivalent-keys.rs":"7abd4e1fb7c1c0ef92fa5a113ae15066ef09bceee8a03bc78aca8ba8dfe9607a","tests/compile-fail-unicase/equivalent-keys.stderr":"c6dbda76b5e7c5e4c4eeca56f231167259f9bc43eb008fe0356db4ee2dae3978","tests/compile-fail/bad-syntax.rs":"14082c0da8cba00c2b9f985b4ef9dc6827f2641b5b0e7dc379eca2f2629109a6","tests/compile-fail/bad-syntax.stderr":"6aa0c2f2acff3225bd16cd0b0871be1be375e1cd6e1297cb01b2f7ec4cd94f7f","tests/compiletest.rs":"923f745b574953deb6e4c2640c95a8af342883eb6d77f9cdccbfed75bcc6adb7","tests/test.rs":"9ec53f46e525138d14ddeb3392f03f7955ab0c78cf276e2f0d0e1f13f7bc9e3c"},"package":"7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"}
\ No newline at end of file diff --git a/third_party/rust/phf_macros/Cargo.toml b/third_party/rust/phf_macros/Cargo.toml new file mode 100644 index 0000000000..be82a1dc02 --- /dev/null +++ b/third_party/rust/phf_macros/Cargo.toml @@ -0,0 +1,50 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "phf_macros" +version = "0.8.0" +authors = ["Steven Fackler <sfackler@gmail.com>"] +description = "Macros to generate types in the phf crate" +license = "MIT" +repository = "https://github.com/sfackler/rust-phf" + +[lib] +proc-macro = true +[dependencies.phf_generator] +version = "0.8.0" + +[dependencies.phf_shared] +version = "0.8.0" + +[dependencies.proc-macro-hack] +version = "0.5.4" + +[dependencies.proc-macro2] +version = "1" + +[dependencies.quote] +version = "1" + +[dependencies.syn] +version = "1" +features = ["full"] +[dev-dependencies.phf] +version = "0.8" +features = ["macros", "unicase"] + +[dev-dependencies.trybuild] +version = "1.0" + +[dev-dependencies.unicase] +version = "2.4.0" diff --git a/third_party/rust/phf_macros/benches/bench.rs b/third_party/rust/phf_macros/benches/bench.rs new file mode 100644 index 0000000000..c0d66ef79d --- /dev/null +++ b/third_party/rust/phf_macros/benches/bench.rs @@ -0,0 +1,130 @@ +#![feature(test)] + +extern crate test; + +mod map { + use std::collections::{BTreeMap, HashMap}; + use test::Bencher; + use phf::phf_map; + + macro_rules! map_and_match { + ($map:ident, $f:ident, $($key:expr => $value:expr,)+) => { + static $map: phf::Map<&'static str, usize> = phf_map! { + $($key => $value),+ + }; + + fn $f(key: &str) -> Option<usize> { + match key { + $($key => Some($value),)+ + _ => None + } + } + } + } + + map_and_match! { MAP, match_get, + "apple" => 0, + "banana" => 1, + "carrot" => 2, + "doughnut" => 3, + "eggplant" => 4, + "frankincene" => 5, + "grapes" => 6, + "haggis" => 7, + "ice cream" => 8, + "jelly beans" => 9, + "kaffir lime leaves" => 10, + "lemonade" => 11, + "mashmallows" => 12, + "nectarines" => 13, + "oranges" => 14, + "pineapples" => 15, + "quinoa" => 16, + "rosemary" => 17, + "sourdough" => 18, + "tomatoes" => 19, + "unleavened bread" => 20, + "vanilla" => 21, + "watermelon" => 22, + "xinomavro grapes" => 23, + "yogurt" => 24, + "zucchini" => 25, + } + + #[bench] + fn bench_match_some(b: &mut Bencher) { + b.iter(|| { + assert_eq!(match_get("zucchini").unwrap(), 25); + }) + } + + #[bench] + fn bench_match_none(b: &mut Bencher) { + b.iter(|| { + assert_eq!(match_get("potato"), None); + }) + } + + #[bench] + fn bench_btreemap_some(b: &mut Bencher) { + let mut map = BTreeMap::new(); + for (key, value) in MAP.entries() { + map.insert(*key, *value); + } + + b.iter(|| { + assert_eq!(map.get("zucchini").unwrap(), &25); + }) + } + + #[bench] + fn bench_hashmap_some(b: &mut Bencher) { + let mut map = HashMap::new(); + for (key, value) in MAP.entries() { + map.insert(*key, *value); + } + + b.iter(|| { + assert_eq!(map.get("zucchini").unwrap(), &25); + }) + } + + #[bench] + fn bench_phf_some(b: &mut Bencher) { + b.iter(|| { + assert_eq!(MAP.get("zucchini").unwrap(), &25); + }) + } + + #[bench] + fn bench_btreemap_none(b: &mut Bencher) { + let mut map = BTreeMap::new(); + for (key, value) in MAP.entries() { + map.insert(*key, *value); + } + + b.iter(|| { + assert_eq!(map.get("potato"), None); + }) + } + + + #[bench] + fn bench_hashmap_none(b: &mut Bencher) { + let mut map = HashMap::new(); + for (key, value) in MAP.entries() { + map.insert(*key, *value); + } + + b.iter(|| { + assert_eq!(map.get("potato"), None); + }) + } + + #[bench] + fn bench_phf_none(b: &mut Bencher) { + b.iter(|| { + assert_eq!(MAP.get("potato"), None); + }) + } +} diff --git a/third_party/rust/phf_macros/src/lib.rs b/third_party/rust/phf_macros/src/lib.rs new file mode 100644 index 0000000000..b1e56ebfcb --- /dev/null +++ b/third_party/rust/phf_macros/src/lib.rs @@ -0,0 +1,242 @@ +extern crate proc_macro; + +use phf_generator::HashState; +use phf_shared::PhfHash; +use proc_macro::TokenStream; +use quote::quote; +use std::collections::HashSet; +use std::hash::Hasher; +use syn::parse::{self, Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::{parse_macro_input, Error, Expr, Lit, Token, UnOp}; + +#[derive(Hash, PartialEq, Eq, Clone)] +enum ParsedKey { + Str(String), + Binary(Vec<u8>), + Char(char), + I8(i8), + I16(i16), + I32(i32), + I64(i64), + I128(i128), + U8(u8), + U16(u16), + U32(u32), + U64(u64), + U128(u128), + Bool(bool), +} + +impl PhfHash for ParsedKey { + fn phf_hash<H>(&self, state: &mut H) + where + H: Hasher, + { + match self { + ParsedKey::Str(s) => s.phf_hash(state), + ParsedKey::Binary(s) => s.phf_hash(state), + ParsedKey::Char(s) => s.phf_hash(state), + ParsedKey::I8(s) => s.phf_hash(state), + ParsedKey::I16(s) => s.phf_hash(state), + ParsedKey::I32(s) => s.phf_hash(state), + ParsedKey::I64(s) => s.phf_hash(state), + ParsedKey::I128(s) => s.phf_hash(state), + ParsedKey::U8(s) => s.phf_hash(state), + ParsedKey::U16(s) => s.phf_hash(state), + ParsedKey::U32(s) => s.phf_hash(state), + ParsedKey::U64(s) => s.phf_hash(state), + ParsedKey::U128(s) => s.phf_hash(state), + ParsedKey::Bool(s) => s.phf_hash(state), + } + } +} + +impl ParsedKey { + fn from_expr(expr: &Expr) -> Option<ParsedKey> { + match expr { + Expr::Lit(lit) => match &lit.lit { + Lit::Str(s) => Some(ParsedKey::Str(s.value())), + Lit::ByteStr(s) => Some(ParsedKey::Binary(s.value())), + Lit::Byte(s) => Some(ParsedKey::U8(s.value())), + Lit::Char(s) => Some(ParsedKey::Char(s.value())), + Lit::Int(s) => match s.suffix() { + // we've lost the sign at this point, so `-128i8` looks like `128i8`, + // which doesn't fit in an `i8`; parse it as a `u8` and cast (to `0i8`), + // which is handled below, by `Unary` + "i8" => Some(ParsedKey::I8(s.base10_parse::<u8>().unwrap() as i8)), + "i16" => Some(ParsedKey::I16(s.base10_parse::<u16>().unwrap() as i16)), + "i32" => Some(ParsedKey::I32(s.base10_parse::<u32>().unwrap() as i32)), + "i64" => Some(ParsedKey::I64(s.base10_parse::<u64>().unwrap() as i64)), + "i128" => Some(ParsedKey::I128(s.base10_parse::<u128>().unwrap() as i128)), + "u8" => Some(ParsedKey::U8(s.base10_parse::<u8>().unwrap())), + "u16" => Some(ParsedKey::U16(s.base10_parse::<u16>().unwrap())), + "u32" => Some(ParsedKey::U32(s.base10_parse::<u32>().unwrap())), + "u64" => Some(ParsedKey::U64(s.base10_parse::<u64>().unwrap())), + "u128" => Some(ParsedKey::U128(s.base10_parse::<u128>().unwrap())), + _ => None, + }, + Lit::Bool(s) => Some(ParsedKey::Bool(s.value)), + _ => None, + }, + Expr::Array(array) => { + let mut buf = vec![]; + for expr in &array.elems { + match expr { + Expr::Lit(lit) => match &lit.lit { + Lit::Int(s) => match s.suffix() { + "u8" | "" => buf.push(s.base10_parse::<u8>().unwrap()), + _ => return None, + }, + _ => return None, + }, + _ => return None, + } + } + Some(ParsedKey::Binary(buf)) + } + Expr::Unary(unary) => { + // if we received an integer literal (always unsigned) greater than i__::max_value() + // then casting it to a signed integer type of the same width will negate it to + // the same absolute value so we don't need to negate it here + macro_rules! try_negate ( + ($val:expr) => {if $val < 0 { $val } else { -$val }} + ); + + match unary.op { + UnOp::Neg(_) => match ParsedKey::from_expr(&unary.expr)? { + ParsedKey::I8(v) => Some(ParsedKey::I8(try_negate!(v))), + ParsedKey::I16(v) => Some(ParsedKey::I16(try_negate!(v))), + ParsedKey::I32(v) => Some(ParsedKey::I32(try_negate!(v))), + ParsedKey::I64(v) => Some(ParsedKey::I64(try_negate!(v))), + ParsedKey::I128(v) => Some(ParsedKey::I128(try_negate!(v))), + _ => None, + }, + _ => None, + } + } + Expr::Group(group) => ParsedKey::from_expr(&group.expr), + _ => None, + } + } +} + +struct Key { + parsed: ParsedKey, + expr: Expr, +} + +impl PhfHash for Key { + fn phf_hash<H>(&self, state: &mut H) + where + H: Hasher, + { + self.parsed.phf_hash(state) + } +} + +impl Parse for Key { + fn parse(input: ParseStream) -> parse::Result<Key> { + let expr = input.parse()?; + let parsed = ParsedKey::from_expr(&expr) + .ok_or_else(|| Error::new_spanned(&expr, "unsupported key expression"))?; + + Ok(Key { parsed, expr }) + } +} + +struct Entry { + key: Key, + value: Expr, +} + +impl PhfHash for Entry { + fn phf_hash<H>(&self, state: &mut H) + where + H: Hasher, + { + self.key.phf_hash(state) + } +} + +impl Parse for Entry { + fn parse(input: ParseStream) -> parse::Result<Entry> { + let key = input.parse()?; + input.parse::<Token![=>]>()?; + let value = input.parse()?; + Ok(Entry { key, value }) + } +} + +struct Map(Vec<Entry>); + +impl Parse for Map { + fn parse(input: ParseStream) -> parse::Result<Map> { + let parsed = Punctuated::<Entry, Token![,]>::parse_terminated(input)?; + let map = parsed.into_iter().collect::<Vec<_>>(); + check_duplicates(&map)?; + Ok(Map(map)) + } +} + +struct Set(Vec<Entry>); + +impl Parse for Set { + fn parse(input: ParseStream) -> parse::Result<Set> { + let parsed = Punctuated::<Key, Token![,]>::parse_terminated(input)?; + let set = parsed + .into_iter() + .map(|key| Entry { + key, + value: syn::parse_str("()").unwrap(), + }) + .collect::<Vec<_>>(); + check_duplicates(&set)?; + Ok(Set(set)) + } +} + +fn check_duplicates(entries: &[Entry]) -> parse::Result<()> { + let mut keys = HashSet::new(); + for entry in entries { + if !keys.insert(&entry.key.parsed) { + return Err(Error::new_spanned(&entry.key.expr, "duplicate key")); + } + } + Ok(()) +} + +fn build_map(entries: &[Entry], state: HashState) -> proc_macro2::TokenStream { + let key = state.key; + let disps = state.disps.iter().map(|&(d1, d2)| quote!((#d1, #d2))); + let entries = state.map.iter().map(|&idx| { + let key = &entries[idx].key.expr; + let value = &entries[idx].value; + quote!((#key, #value)) + }); + + quote! { + phf::Map { + key: #key, + disps: phf::Slice::Static(&[#(#disps),*]), + entries: phf::Slice::Static(&[#(#entries),*]), + } + } +} + +#[::proc_macro_hack::proc_macro_hack] +pub fn phf_map(input: TokenStream) -> TokenStream { + let map = parse_macro_input!(input as Map); + let state = phf_generator::generate_hash(&map.0); + + build_map(&map.0, state).into() +} + +#[::proc_macro_hack::proc_macro_hack] +pub fn phf_set(input: TokenStream) -> TokenStream { + let set = parse_macro_input!(input as Set); + let state = phf_generator::generate_hash(&set.0); + + let map = build_map(&set.0, state); + quote!(phf::Set { map: #map }).into() +} diff --git a/third_party/rust/phf_macros/tests/compile-fail-unicase/equivalent-keys.rs b/third_party/rust/phf_macros/tests/compile-fail-unicase/equivalent-keys.rs new file mode 100644 index 0000000000..45291354cc --- /dev/null +++ b/third_party/rust/phf_macros/tests/compile-fail-unicase/equivalent-keys.rs @@ -0,0 +1,9 @@ +use unicase::UniCase; +use phf::phf_map; + +static MAP: phf::Map<UniCase<&'static str>, isize> = phf_map!( //~ ERROR duplicate key UniCase("FOO") + UniCase("FOO") => 42, //~ NOTE one occurrence here + UniCase("foo") => 42, //~ NOTE one occurrence here +); + +fn main() {} diff --git a/third_party/rust/phf_macros/tests/compile-fail-unicase/equivalent-keys.stderr b/third_party/rust/phf_macros/tests/compile-fail-unicase/equivalent-keys.stderr new file mode 100644 index 0000000000..b0e1d1012f --- /dev/null +++ b/third_party/rust/phf_macros/tests/compile-fail-unicase/equivalent-keys.stderr @@ -0,0 +1,5 @@ +error: unsupported key expression + --> $DIR/equivalent-keys.rs:5:5 + | +5 | UniCase("FOO") => 42, //~ NOTE one occurrence here + | ^^^^^^^^^^^^^^ diff --git a/third_party/rust/phf_macros/tests/compile-fail/bad-syntax.rs b/third_party/rust/phf_macros/tests/compile-fail/bad-syntax.rs new file mode 100644 index 0000000000..a766be4283 --- /dev/null +++ b/third_party/rust/phf_macros/tests/compile-fail/bad-syntax.rs @@ -0,0 +1,9 @@ +use phf::phf_map; + +static MAP: phf::Map<u32, u32> = phf_map! { + Signature:: + => //~ ERROR expected identifier + () +}; + +fn main() {} diff --git a/third_party/rust/phf_macros/tests/compile-fail/bad-syntax.stderr b/third_party/rust/phf_macros/tests/compile-fail/bad-syntax.stderr new file mode 100644 index 0000000000..bd387e6dcc --- /dev/null +++ b/third_party/rust/phf_macros/tests/compile-fail/bad-syntax.stderr @@ -0,0 +1,5 @@ +error: expected identifier + --> $DIR/bad-syntax.rs:5:5 + | +5 | => //~ ERROR expected identifier + | ^^ diff --git a/third_party/rust/phf_macros/tests/compiletest.rs b/third_party/rust/phf_macros/tests/compiletest.rs new file mode 100644 index 0000000000..c95f3c8073 --- /dev/null +++ b/third_party/rust/phf_macros/tests/compiletest.rs @@ -0,0 +1,13 @@ +#[test] +#[ignore] // compiler error message format is different between 1.32.0 and nightly +fn compile_test_unicase() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/compile-fail-unicase/*.rs"); +} + +#[test] +#[ignore] +fn compile_fail() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/compile-fail/*.rs"); +} diff --git a/third_party/rust/phf_macros/tests/test.rs b/third_party/rust/phf_macros/tests/test.rs new file mode 100644 index 0000000000..05caa41138 --- /dev/null +++ b/third_party/rust/phf_macros/tests/test.rs @@ -0,0 +1,324 @@ +mod map { + use std::collections::{HashMap, HashSet}; + use phf::phf_map; + + #[allow(dead_code)] + static TRAILING_COMMA: phf::Map<&'static str, isize> = phf_map!( + "foo" => 10, + ); + + #[allow(dead_code)] + static NO_TRAILING_COMMA: phf::Map<&'static str, isize> = phf_map!( + "foo" => 10 + ); + + #[allow(dead_code)] + static BYTE_STRING_KEY: phf::Map<&'static [u8], &'static str> = phf_map!( + b"camembert" => "delicious", + ); + + #[test] + fn test_two() { + static MAP: phf::Map<&'static str, isize> = phf_map!( + "foo" => 10, + "bar" => 11, + ); + assert!(Some(&10) == MAP.get(&("foo"))); + assert!(Some(&11) == MAP.get(&("bar"))); + assert_eq!(None, MAP.get(&("asdf"))); + assert_eq!(2, MAP.len()); + } + + #[test] + fn test_entries() { + static MAP: phf::Map<&'static str, isize> = phf_map!( + "foo" => 10, + "bar" => 11, + ); + let hash = MAP.entries().map(|(&k, &v)| (k, v)).collect::<HashMap<_, isize>>(); + assert!(Some(&10) == hash.get(&("foo"))); + assert!(Some(&11) == hash.get(&("bar"))); + assert_eq!(2, hash.len()); + } + + #[test] + fn test_keys() { + static MAP: phf::Map<&'static str, isize> = phf_map!( + "foo" => 10, + "bar" => 11, + ); + let hash = MAP.keys().map(|&e| e).collect::<HashSet<_>>(); + assert!(hash.contains(&("foo"))); + assert!(hash.contains(&("bar"))); + assert_eq!(2, hash.len()); + } + + #[test] + fn test_values() { + static MAP: phf::Map<&'static str, isize> = phf_map!( + "foo" => 10, + "bar" => 11, + ); + let hash = MAP.values().map(|&e| e).collect::<HashSet<isize>>(); + assert!(hash.contains(&10)); + assert!(hash.contains(&11)); + assert_eq!(2, hash.len()); + } + + #[test] + fn test_large() { + static MAP: phf::Map<&'static str, isize> = phf_map!( + "a" => 0, + "b" => 1, + "c" => 2, + "d" => 3, + "e" => 4, + "f" => 5, + "g" => 6, + "h" => 7, + "i" => 8, + "j" => 9, + "k" => 10, + "l" => 11, + "m" => 12, + "n" => 13, + "o" => 14, + "p" => 15, + "q" => 16, + "r" => 17, + "s" => 18, + "t" => 19, + "u" => 20, + "v" => 21, + "w" => 22, + "x" => 23, + "y" => 24, + "z" => 25, + ); + assert!(MAP.get(&("a")) == Some(&0)); + } + + #[test] + fn test_non_static_str_key() { + static MAP: phf::Map<&'static str, isize> = phf_map!( + "a" => 0, + ); + assert_eq!(Some(&0), MAP.get(&*"a".to_string())); + } + + #[test] + fn test_index_ok() { + static MAP: phf::Map<&'static str, isize> = phf_map!( + "a" => 0, + ); + assert_eq!(0, MAP["a"]); + } + + #[test] + #[should_panic] + fn test_index_fail() { + static MAP: phf::Map<&'static str, isize> = phf_map!( + "a" => 0, + ); + MAP["b"]; + } + + macro_rules! test_key_type( + ($t:ty, $($k:expr => $v:expr),+) => ({ + static MAP: phf::Map<$t, isize> = phf_map! { + $($k => $v),+ + }; + $( + assert_eq!(Some(&$v), MAP.get(&$k)); + )+ + }) + ); + + #[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], isize> = phf_map!( + [0u8, 1] => 0, + [2, 3u8] => 1, + [4, 5] => 2, + ); + assert_eq!(Some(&0), MAP.get(&[0u8, 1u8])); + } + + #[test] + fn test_byte_keys() { + test_key_type!(u8, b'a' => 0, b'b' => 1); + } + + #[test] + fn test_char_keys() { + test_key_type!(char, 'a' => 0, 'b' => 1); + } + + #[test] + fn test_i8_keys() { + test_key_type!(i8, 0i8 => 0, 1i8 => 1, 127i8 => 2, -128i8 => 3); + } + + #[test] + fn test_i16_keys() { + test_key_type!(i16, 0i16 => 0, 1i16 => 1, 32767i16 => 2, -32768i16 => 3); + } + + #[test] + fn test_i32_keys() { + test_key_type!(i32, 0i32 => 0, 1i32 => 1, 2147483647i32 => 2, -2147483648i32 => 3); + } + + #[test] + fn test_i64_keys() { + test_key_type!(i64, 0i64 => 0, 1i64 => 1, -9223372036854775808i64 => 2); + } + + #[test] + fn test_i128_keys() { + test_key_type!( + i128, 0i128 => 0, 1i128 => 1, + // `syn` handles literals larger than 64-bit differently + 170141183460469231731687303715884105727i128 => 2, + -170141183460469231731687303715884105727i128 => 3 + ); + } + + #[test] + fn test_u8_keys() { + test_key_type!(u8, 0u8 => 0, 1u8 => 1, 255u8 => 2); + } + + #[test] + fn test_u16_keys() { + test_key_type!(u16, 0u16 => 0, 1u16 => 1, 65535u16 => 2); + } + + #[test] + fn test_u32_keys() { + test_key_type!(u32, 0u32 => 0, 1u32 => 1, 4294967295u32 => 2); + } + + #[test] + fn test_u64_keys() { + test_key_type!(u64, 0u64 => 0, 1u64 => 1, 18446744073709551615u64 => 2); + } + + #[test] + fn test_u128_keys() { + test_key_type!( + u128, 0u128 => 0, 1u128 => 1, + 340282366920938463463374607431768211455u128 => 2 + ); + } + + #[test] + fn test_bool_keys() { + test_key_type!(bool, false => 0, true => 1); + } + + #[test] + fn test_into_iterator() { + static MAP: phf::Map<&'static str, isize> = phf_map!( + "foo" => 10, + ); + + for (k, v) in &MAP { + assert_eq!(&"foo", k); + assert_eq!(&10, v) + } + } + + #[cfg(feature = "unicase_support")] + #[test] + fn test_unicase() { + use unicase::UniCase; + static MAP: phf::Map<UniCase<&'static str>, isize> = phf_map!( + UniCase("FOO") => 10, + UniCase("Bar") => 11, + ); + assert!(Some(&10) == MAP.get(&UniCase("FOo"))); + assert!(Some(&11) == MAP.get(&UniCase("bar"))); + assert_eq!(None, MAP.get(&UniCase("asdf"))); + } + + #[cfg(feature = "unicase_support")] + #[test] + fn test_unicase_alt() { + use unicase; + static MAP: phf::Map<unicase::UniCase<&'static str>, isize> = phf_map!( + unicase::UniCase("FOO") => 10, + unicase::UniCase("Bar") => 11, + ); + assert!(Some(&10) == MAP.get(&unicase::UniCase("FOo"))); + assert!(Some(&11) == MAP.get(&unicase::UniCase("bar"))); + assert_eq!(None, MAP.get(&unicase::UniCase("asdf"))); + } +} + +mod set { + use std::collections::HashSet; + use phf::phf_set; + + #[allow(dead_code)] + static TRAILING_COMMA: phf::Set<&'static str> = phf_set! { + "foo", + }; + + #[allow(dead_code)] + static NO_TRAILING_COMMA: phf::Set<&'static str> = phf_set! { + "foo" + }; + + #[test] + fn test_two() { + static SET: phf::Set<&'static str> = phf_set! { + "hello", + "world", + }; + assert!(SET.contains(&"hello")); + assert!(SET.contains(&"world")); + assert!(!SET.contains(&"foo")); + assert_eq!(2, SET.len()); + } + + #[test] + fn test_iter() { + static SET: phf::Set<&'static str> = phf_set! { + "hello", + "world", + }; + let set = SET.iter().map(|e| *e).collect::<HashSet<_>>(); + assert!(set.contains(&"hello")); + assert!(set.contains(&"world")); + assert_eq!(2, set.len()); + } + + #[test] + fn test_non_static_str_contains() { + static SET: phf::Set<&'static str> = phf_set! { + "hello", + "world", + }; + assert!(SET.contains(&*"hello".to_string())); + } + + #[test] + fn test_into_iterator() { + static SET: phf::Set<&'static str> = phf_set! { + "hello", + }; + + for e in &SET { + assert_eq!(&"hello", e); + } + } +} |