Skip to content

Commit

Permalink
Add support for uncased
Browse files Browse the repository at this point in the history
uncased is an ASCII-only case insensitive comparison library like
UniCase, but it has better support for being used in a map.

Specifically, UniCase does not support the Borrow trait (see
seanmonstar/unicase#22), so the type

    phf::Map<UniCase<&'static str>, _>

only supports lookups with static string literals, which has limited
usefulness.

By contrast, the the equivalent uncased construction

    phf::Map<&'static Uncased, _>

*does* support lookups with non-static strings.
  • Loading branch information
benesch committed Nov 6, 2020
1 parent 8dce12c commit 68e18e1
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 1 deletion.
1 change: 1 addition & 0 deletions phf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ test = false
[features]
default = ["std"]
std = ["phf_shared/std"]
uncased = ["phf_shared/uncased"]
unicase = ["phf_shared/unicase"]
macros = [
"phf_macros",
Expand Down
4 changes: 3 additions & 1 deletion phf_codegen/test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ build = "build.rs"
edition = "2018"

[dependencies]
uncased = "0.9.3"
unicase = "2.4.0"

[build-dependencies]
uncased = "0.9.3"
unicase = "2.4.0"

[build-dependencies.phf_codegen]
path = ".."

[dependencies.phf]
path = "../../phf"
features = ["unicase"]
features = ["uncased", "unicase"]
11 changes: 11 additions & 0 deletions phf_codegen/test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::fs::File;
use std::io::{self, BufWriter, Write};
use std::path::Path;

use uncased::UncasedStr;
use unicase::UniCase;

fn main() -> io::Result<()> {
Expand Down Expand Up @@ -51,6 +52,16 @@ fn main() -> io::Result<()> {
.build()
)?;

write!(
&mut file,
"static UNCASED_MAP: ::phf::Map<&'static ::uncased::UncasedStr, &'static str> = \n{};",
phf_codegen::Map::new()
.entry(UncasedStr::new("abc"), "\"a\"")
.entry(UncasedStr::new("DEF"), "\"b\"")
.build()
)?;


//u32 is used here purely for a type that impls `Hash+PhfHash+Eq+fmt::Debug`, but is not required for the empty test itself
writeln!(&mut file,
"static EMPTY: ::phf::Map<u32, u32> = \n{};",
Expand Down
10 changes: 10 additions & 0 deletions phf_codegen/test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[cfg(test)]
mod test {
use uncased::UncasedStr;
use unicase::UniCase;

include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
Expand Down Expand Up @@ -35,6 +36,15 @@ mod test {
assert!(!UNICASE_MAP.contains_key(&UniCase::new("XyZ")));
}

#[test]
fn uncased_map() {
assert_eq!("a", UNCASED_MAP[&UncasedStr::new("AbC")]);
assert_eq!("a", UNCASED_MAP[&UncasedStr::new("abc")]);
assert_eq!("b", UNCASED_MAP[&UncasedStr::new("DEf")]);
assert!(!UNCASED_MAP.contains_key(&UncasedStr::new("XyZ")));
}


#[test]
fn array_keys() {
assert_eq!(0, ARRAY_KEYS[b"foo"]);
Expand Down
1 change: 1 addition & 0 deletions phf_shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ std = []
[dependencies]
siphasher = "0.3"
unicase = { version = "2.4.0", optional = true }
uncased = { version = "0.9.3", optional = true, default-features = false }
20 changes: 20 additions & 0 deletions phf_shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,26 @@ impl<S> FmtConst for unicase::UniCase<S> where S: AsRef<str> {
}
}

#[cfg(feature = "uncased")]
impl PhfHash for uncased::UncasedStr {
#[inline]
fn phf_hash<H: Hasher>(&self, state: &mut H) {
self.hash(state)
}
}

#[cfg(feature = "uncased")]
impl FmtConst for uncased::UncasedStr {
fn fmt_const(&self, f: &mut fmt::Formatter) -> fmt::Result {
// transmute is not stable in const fns (rust-lang/rust#53605), so
// `UncasedStr::new` can't be a const fn itself, but we can inline the
// call to transmute here in the meantime.
f.write_str("unsafe { ::std::mem::transmute::<&'static str, &'static UncasedStr>(")?;
self.as_str().fmt_const(f)?;
f.write_str(") }")
}
}

macro_rules! sip_impl (
(le $t:ty) => (
impl PhfHash for $t {
Expand Down

0 comments on commit 68e18e1

Please sign in to comment.