summaryrefslogtreecommitdiffstats
path: root/vendor/phf
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/phf
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--vendor/phf/.cargo-checksum.json1
-rw-r--r--vendor/phf/Cargo.toml49
-rw-r--r--vendor/phf/src/lib.rs157
-rw-r--r--vendor/phf/src/map.rs301
-rw-r--r--vendor/phf/src/ordered_map.rs312
-rw-r--r--vendor/phf/src/ordered_set.rs170
-rw-r--r--vendor/phf/src/set.rs147
-rw-r--r--vendor/phf_codegen/.cargo-checksum.json1
-rw-r--r--vendor/phf_codegen/Cargo.toml25
-rw-r--r--vendor/phf_codegen/src/lib.rs486
-rw-r--r--vendor/phf_generator/.cargo-checksum.json1
-rw-r--r--vendor/phf_generator/Cargo.lock679
-rw-r--r--vendor/phf_generator/Cargo.toml40
-rw-r--r--vendor/phf_generator/benches/benches.rs58
-rw-r--r--vendor/phf_generator/src/bin/gen_hash_test.rs20
-rw-r--r--vendor/phf_generator/src/lib.rs105
-rw-r--r--vendor/phf_shared/.cargo-checksum.json1
-rw-r--r--vendor/phf_shared/Cargo.toml39
-rw-r--r--vendor/phf_shared/src/lib.rs421
19 files changed, 3013 insertions, 0 deletions
diff --git a/vendor/phf/.cargo-checksum.json b/vendor/phf/.cargo-checksum.json
new file mode 100644
index 000000000..7c54676c1
--- /dev/null
+++ b/vendor/phf/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"29149d1a0e11a422264675eb6229a7827acf187d1c5f8cc4b9c1cb2bf4ac9ae4","src/lib.rs":"a4d7dede221bdc3d69939a066a058e1a627e57777f7beab1baa93e452eb8fe67","src/map.rs":"755c39145d701560be45c731e81f9e3e60c884d00d1b6dea8e4614f9278a9d88","src/ordered_map.rs":"0b18597047bd5c782ccd4b2f54122e88cd020f930aa6f1436c3c5819d729decf","src/ordered_set.rs":"0ed66947623c8a79b1ad2c206ef5a13af701f95c0f36544ab986c9617e2a24a3","src/set.rs":"065a501930c4667877168b99aeca00007dd222865bafc26451cbc9fdf08ad7e6"},"package":"fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"} \ No newline at end of file
diff --git a/vendor/phf/Cargo.toml b/vendor/phf/Cargo.toml
new file mode 100644
index 000000000..ca2ce9893
--- /dev/null
+++ b/vendor/phf/Cargo.toml
@@ -0,0 +1,49 @@
+# 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 are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "phf"
+version = "0.10.1"
+authors = ["Steven Fackler <sfackler@gmail.com>"]
+description = "Runtime support for perfect hash function data structures"
+readme = "../README.md"
+license = "MIT"
+repository = "https://github.com/sfackler/rust-phf"
+[package.metadata.docs.rs]
+features = ["macros"]
+
+[lib]
+name = "phf"
+path = "src/lib.rs"
+test = false
+[dependencies.phf_macros]
+version = "0.10.0"
+optional = true
+
+[dependencies.phf_shared]
+version = "0.10.0"
+default-features = false
+
+[dependencies.proc-macro-hack]
+version = "0.5.4"
+optional = true
+
+[dependencies.serde]
+version = "1.0"
+optional = true
+
+[features]
+default = ["std"]
+macros = ["phf_macros", "proc-macro-hack"]
+std = ["phf_shared/std"]
+uncased = ["phf_shared/uncased"]
+unicase = ["phf_shared/unicase"]
diff --git a/vendor/phf/src/lib.rs b/vendor/phf/src/lib.rs
new file mode 100644
index 000000000..e60f524b0
--- /dev/null
+++ b/vendor/phf/src/lib.rs
@@ -0,0 +1,157 @@
+//! Rust-PHF is a library to generate efficient lookup tables at compile time using
+//! [perfect hash functions](http://en.wikipedia.org/wiki/Perfect_hash_function).
+//!
+//! It currently uses the
+//! [CHD algorithm](http://cmph.sourceforge.net/papers/esa09.pdf) and can generate
+//! a 100,000 entry map in roughly .4 seconds. By default statistics are not
+//! produced, but if you set the environment variable `PHF_STATS` it will issue
+//! a compiler note about how long it took.
+//!
+//! MSRV (minimum supported rust version) is Rust 1.46.
+//!
+//! ## Usage
+//!
+//! PHF data structures can be constructed via either the procedural
+//! macros in the `phf_macros` crate or code generation supported by the
+//! `phf_codegen` crate. If you prefer macros, you can easily use them by
+//! enabling the `macros` feature of the `phf` crate, like:
+//!
+//!```toml
+//! [dependencies]
+//! phf = { version = "0.10", features = ["macros"] }
+//! ```
+//!
+//! To compile the `phf` crate with a dependency on
+//! libcore instead of libstd, enabling use in environments where libstd
+//! will not work, set `default-features = false` for the dependency:
+//!
+//! ```toml
+//! [dependencies]
+//! # to use `phf` in `no_std` environments
+//! phf = { version = "0.10", default-features = false }
+//! ```
+//!
+//! ## Example (with the `macros` feature enabled)
+//!
+//! ```rust
+//! use phf::phf_map;
+//!
+//! #[derive(Clone)]
+//! pub enum Keyword {
+//! Loop,
+//! Continue,
+//! Break,
+//! Fn,
+//! Extern,
+//! }
+//!
+//! static KEYWORDS: phf::Map<&'static str, Keyword> = phf_map! {
+//! "loop" => Keyword::Loop,
+//! "continue" => Keyword::Continue,
+//! "break" => Keyword::Break,
+//! "fn" => Keyword::Fn,
+//! "extern" => Keyword::Extern,
+//! };
+//!
+//! pub fn parse_keyword(keyword: &str) -> Option<Keyword> {
+//! KEYWORDS.get(keyword).cloned()
+//! }
+//! ```
+//!
+//! Alternatively, you can use the [`phf_codegen`] crate to generate PHF datatypes
+//! in a build script.
+//!
+//! [`phf_codegen`]: https://docs.rs/phf_codegen
+//!
+//! ## Note
+//!
+//! Currently, the macro syntax has some limitations and may not
+//! work as you want. See [#183] or [#196] for example.
+//!
+//! [#183]: https://github.com/rust-phf/rust-phf/issues/183
+//! [#196]: https://github.com/rust-phf/rust-phf/issues/196
+
+#![doc(html_root_url = "https://docs.rs/phf/0.10")]
+#![warn(missing_docs)]
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#[cfg(feature = "std")]
+extern crate std as core;
+
+#[cfg(feature = "macros")]
+/// Macro to create a `static` (compile-time) [`Map`].
+///
+/// Requires the `macros` feature.
+///
+/// Supported key expressions are:
+/// - literals: bools, (byte) strings, bytes, chars, and integers (these must have a type suffix)
+/// - arrays of `u8` integers
+/// - `UniCase::unicode(string)` or `UniCase::ascii(string)` if the `unicase` feature is enabled
+///
+/// # Example
+///
+/// ```
+/// use phf::{phf_map, Map};
+///
+/// static MY_MAP: Map<&'static str, u32> = phf_map! {
+/// "hello" => 1,
+/// "world" => 2,
+/// };
+///
+/// fn main () {
+/// assert_eq!(MY_MAP["hello"], 1);
+/// }
+/// ```
+#[proc_macro_hack::proc_macro_hack]
+pub use phf_macros::phf_map;
+
+#[cfg(feature = "macros")]
+/// Macro to create a `static` (compile-time) [`OrderedMap`].
+///
+/// Requires the `macros` feature. Same usage as [`phf_map`].
+#[proc_macro_hack::proc_macro_hack]
+pub use phf_macros::phf_ordered_map;
+
+#[cfg(feature = "macros")]
+/// Macro to create a `static` (compile-time) [`Set`].
+///
+/// Requires the `macros` feature.
+///
+/// # Example
+///
+/// ```
+/// use phf::{phf_set, Set};
+///
+/// static MY_SET: Set<&'static str> = phf_set! {
+/// "hello world",
+/// "hola mundo",
+/// };
+///
+/// fn main () {
+/// assert!(MY_SET.contains("hello world"));
+/// }
+/// ```
+#[proc_macro_hack::proc_macro_hack]
+pub use phf_macros::phf_set;
+
+#[cfg(feature = "macros")]
+/// Macro to create a `static` (compile-time) [`OrderedSet`].
+///
+/// Requires the `macros` feature. Same usage as [`phf_set`].
+#[proc_macro_hack::proc_macro_hack]
+pub use phf_macros::phf_ordered_set;
+
+#[doc(inline)]
+pub use self::map::Map;
+#[doc(inline)]
+pub use self::ordered_map::OrderedMap;
+#[doc(inline)]
+pub use self::ordered_set::OrderedSet;
+#[doc(inline)]
+pub use self::set::Set;
+pub use phf_shared::PhfHash;
+
+pub mod map;
+pub mod ordered_map;
+pub mod ordered_set;
+pub mod set;
diff --git a/vendor/phf/src/map.rs b/vendor/phf/src/map.rs
new file mode 100644
index 000000000..5b74445c1
--- /dev/null
+++ b/vendor/phf/src/map.rs
@@ -0,0 +1,301 @@
+//! An immutable map constructed at compile time.
+use core::fmt;
+use core::iter::FusedIterator;
+use core::iter::IntoIterator;
+use core::ops::Index;
+use core::slice;
+use phf_shared::{self, HashKey, PhfBorrow, PhfHash};
+#[cfg(feature = "serde")]
+use serde::ser::{Serialize, SerializeMap, Serializer};
+
+/// An immutable map constructed at compile time.
+///
+/// ## Note
+///
+/// The fields of this struct are public so that they may be initialized by the
+/// `phf_map!` macro and code generation. They are subject to change at any
+/// time and should never be accessed directly.
+pub struct Map<K: 'static, V: 'static> {
+ #[doc(hidden)]
+ pub key: HashKey,
+ #[doc(hidden)]
+ pub disps: &'static [(u32, u32)],
+ #[doc(hidden)]
+ pub entries: &'static [(K, V)],
+}
+
+impl<K, V> fmt::Debug for Map<K, V>
+where
+ K: fmt::Debug,
+ V: fmt::Debug,
+{
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map().entries(self.entries()).finish()
+ }
+}
+
+impl<'a, K, V, T: ?Sized> Index<&'a T> for Map<K, V>
+where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+{
+ type Output = V;
+
+ fn index(&self, k: &'a T) -> &V {
+ self.get(k).expect("invalid key")
+ }
+}
+
+impl<K, V> Map<K, V> {
+ /// Returns the number of entries in the `Map`.
+ #[inline]
+ pub const fn len(&self) -> usize {
+ self.entries.len()
+ }
+
+ /// Returns true if the `Map` is empty.
+ #[inline]
+ pub const fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
+ /// Determines if `key` is in the `Map`.
+ pub fn contains_key<T: ?Sized>(&self, key: &T) -> bool
+ where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+ {
+ self.get(key).is_some()
+ }
+
+ /// Returns a reference to the value that `key` maps to.
+ pub fn get<T: ?Sized>(&self, key: &T) -> Option<&V>
+ where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+ {
+ self.get_entry(key).map(|e| e.1)
+ }
+
+ /// Returns a reference to the map's internal static instance of the given
+ /// key.
+ ///
+ /// This can be useful for interning schemes.
+ pub fn get_key<T: ?Sized>(&self, key: &T) -> Option<&K>
+ where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+ {
+ self.get_entry(key).map(|e| e.0)
+ }
+
+ /// Like `get`, but returns both the key and the value.
+ pub fn get_entry<T: ?Sized>(&self, key: &T) -> Option<(&K, &V)>
+ where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+ {
+ if self.disps.is_empty() {
+ return None;
+ } //Prevent panic on empty map
+ let hashes = phf_shared::hash(key, &self.key);
+ let index = phf_shared::get_index(&hashes, &*self.disps, self.entries.len());
+ let entry = &self.entries[index as usize];
+ let b: &T = entry.0.borrow();
+ if b == key {
+ Some((&entry.0, &entry.1))
+ } else {
+ None
+ }
+ }
+
+ /// Returns an iterator over the key/value pairs in the map.
+ ///
+ /// Entries are returned in an arbitrary but fixed order.
+ pub fn entries(&self) -> Entries<'_, K, V> {
+ Entries {
+ iter: self.entries.iter(),
+ }
+ }
+
+ /// Returns an iterator over the keys in the map.
+ ///
+ /// Keys are returned in an arbitrary but fixed order.
+ pub fn keys(&self) -> Keys<'_, K, V> {
+ Keys {
+ iter: self.entries(),
+ }
+ }
+
+ /// Returns an iterator over the values in the map.
+ ///
+ /// Values are returned in an arbitrary but fixed order.
+ pub fn values(&self) -> Values<'_, K, V> {
+ Values {
+ iter: self.entries(),
+ }
+ }
+}
+
+impl<'a, K, V> IntoIterator for &'a Map<K, V> {
+ type Item = (&'a K, &'a V);
+ type IntoIter = Entries<'a, K, V>;
+
+ fn into_iter(self) -> Entries<'a, K, V> {
+ self.entries()
+ }
+}
+
+/// An iterator over the key/value pairs in a `Map`.
+pub struct Entries<'a, K, V> {
+ iter: slice::Iter<'a, (K, V)>,
+}
+
+impl<'a, K, V> Clone for Entries<'a, K, V> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Self {
+ iter: self.iter.clone(),
+ }
+ }
+}
+
+impl<'a, K, V> fmt::Debug for Entries<'a, K, V>
+where
+ K: fmt::Debug,
+ V: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_list().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, K, V> Iterator for Entries<'a, K, V> {
+ type Item = (&'a K, &'a V);
+
+ fn next(&mut self) -> Option<(&'a K, &'a V)> {
+ self.iter.next().map(|&(ref k, ref v)| (k, v))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, K, V> DoubleEndedIterator for Entries<'a, K, V> {
+ fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
+ self.iter.next_back().map(|e| (&e.0, &e.1))
+ }
+}
+
+impl<'a, K, V> ExactSizeIterator for Entries<'a, K, V> {}
+
+impl<'a, K, V> FusedIterator for Entries<'a, K, V> {}
+
+/// An iterator over the keys in a `Map`.
+pub struct Keys<'a, K, V> {
+ iter: Entries<'a, K, V>,
+}
+
+impl<'a, K, V> Clone for Keys<'a, K, V> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Self {
+ iter: self.iter.clone(),
+ }
+ }
+}
+
+impl<'a, K, V> fmt::Debug for Keys<'a, K, V>
+where
+ K: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_list().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, K, V> Iterator for Keys<'a, K, V> {
+ type Item = &'a K;
+
+ fn next(&mut self) -> Option<&'a K> {
+ self.iter.next().map(|e| e.0)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
+ fn next_back(&mut self) -> Option<&'a K> {
+ self.iter.next_back().map(|e| e.0)
+ }
+}
+
+impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {}
+
+impl<'a, K, V> FusedIterator for Keys<'a, K, V> {}
+
+/// An iterator over the values in a `Map`.
+pub struct Values<'a, K, V> {
+ iter: Entries<'a, K, V>,
+}
+
+impl<'a, K, V> Clone for Values<'a, K, V> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Self {
+ iter: self.iter.clone(),
+ }
+ }
+}
+
+impl<'a, K, V> fmt::Debug for Values<'a, K, V>
+where
+ V: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_list().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, K, V> Iterator for Values<'a, K, V> {
+ type Item = &'a V;
+
+ fn next(&mut self) -> Option<&'a V> {
+ self.iter.next().map(|e| e.1)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
+ fn next_back(&mut self) -> Option<&'a V> {
+ self.iter.next_back().map(|e| e.1)
+ }
+}
+
+impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}
+
+impl<'a, K, V> FusedIterator for Values<'a, K, V> {}
+
+#[cfg(feature = "serde")]
+impl<K, V> Serialize for Map<K, V>
+where
+ K: Serialize,
+ V: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut map = serializer.serialize_map(Some(self.len()))?;
+ for (k, v) in self.entries() {
+ map.serialize_entry(k, v)?;
+ }
+ map.end()
+ }
+}
diff --git a/vendor/phf/src/ordered_map.rs b/vendor/phf/src/ordered_map.rs
new file mode 100644
index 000000000..c8d5ac59b
--- /dev/null
+++ b/vendor/phf/src/ordered_map.rs
@@ -0,0 +1,312 @@
+//! An order-preserving immutable map constructed at compile time.
+use core::fmt;
+use core::iter::FusedIterator;
+use core::iter::IntoIterator;
+use core::ops::Index;
+use core::slice;
+use phf_shared::{self, HashKey, PhfBorrow, PhfHash};
+
+/// An order-preserving immutable map constructed at compile time.
+///
+/// Unlike a `Map`, iteration order is guaranteed to match the definition
+/// order.
+///
+/// ## Note
+///
+/// The fields of this struct are public so that they may be initialized by the
+/// `phf_ordered_map!` macro and code generation. They are subject to change at
+/// any time and should never be accessed directly.
+pub struct OrderedMap<K: 'static, V: 'static> {
+ #[doc(hidden)]
+ pub key: HashKey,
+ #[doc(hidden)]
+ pub disps: &'static [(u32, u32)],
+ #[doc(hidden)]
+ pub idxs: &'static [usize],
+ #[doc(hidden)]
+ pub entries: &'static [(K, V)],
+}
+
+impl<K, V> fmt::Debug for OrderedMap<K, V>
+where
+ K: fmt::Debug,
+ V: fmt::Debug,
+{
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_map().entries(self.entries()).finish()
+ }
+}
+
+impl<'a, K, V, T: ?Sized> Index<&'a T> for OrderedMap<K, V>
+where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+{
+ type Output = V;
+
+ fn index(&self, k: &'a T) -> &V {
+ self.get(k).expect("invalid key")
+ }
+}
+
+impl<K, V> OrderedMap<K, V> {
+ /// Returns the number of entries in the `OrderedMap`.
+ #[inline]
+ pub const fn len(&self) -> usize {
+ self.entries.len()
+ }
+
+ /// Returns true if the `OrderedMap` is empty.
+ #[inline]
+ pub const fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
+ /// Returns a reference to the value that `key` maps to.
+ pub fn get<T: ?Sized>(&self, key: &T) -> Option<&V>
+ where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+ {
+ self.get_entry(key).map(|e| e.1)
+ }
+
+ /// Returns a reference to the map's internal static instance of the given
+ /// key.
+ ///
+ /// This can be useful for interning schemes.
+ pub fn get_key<T: ?Sized>(&self, key: &T) -> Option<&K>
+ where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+ {
+ self.get_entry(key).map(|e| e.0)
+ }
+
+ /// Determines if `key` is in the `OrderedMap`.
+ pub fn contains_key<T: ?Sized>(&self, key: &T) -> bool
+ where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+ {
+ self.get(key).is_some()
+ }
+
+ /// Returns the index of the key within the list used to initialize
+ /// the ordered map.
+ pub fn get_index<T: ?Sized>(&self, key: &T) -> Option<usize>
+ where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+ {
+ self.get_internal(key).map(|(i, _)| i)
+ }
+
+ /// Returns references to both the key and values at an index
+ /// within the list used to initialize the ordered map. See `.get_index(key)`.
+ pub fn index(&self, index: usize) -> Option<(&K, &V)> {
+ self.entries.get(index).map(|&(ref k, ref v)| (k, v))
+ }
+
+ /// Like `get`, but returns both the key and the value.
+ pub fn get_entry<T: ?Sized>(&self, key: &T) -> Option<(&K, &V)>
+ where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+ {
+ self.get_internal(key).map(|(_, e)| e)
+ }
+
+ fn get_internal<T: ?Sized>(&self, key: &T) -> Option<(usize, (&K, &V))>
+ where
+ T: Eq + PhfHash,
+ K: PhfBorrow<T>,
+ {
+ if self.disps.is_empty() {
+ return None;
+ } //Prevent panic on empty map
+ let hashes = phf_shared::hash(key, &self.key);
+ let idx_index = phf_shared::get_index(&hashes, &*self.disps, self.idxs.len());
+ let idx = self.idxs[idx_index as usize];
+ let entry = &self.entries[idx];
+
+ let b: &T = entry.0.borrow();
+ if b == key {
+ Some((idx, (&entry.0, &entry.1)))
+ } else {
+ None
+ }
+ }
+
+ /// Returns an iterator over the key/value pairs in the map.
+ ///
+ /// Entries are returned in the same order in which they were defined.
+ pub fn entries(&self) -> Entries<'_, K, V> {
+ Entries {
+ iter: self.entries.iter(),
+ }
+ }
+
+ /// Returns an iterator over the keys in the map.
+ ///
+ /// Keys are returned in the same order in which they were defined.
+ pub fn keys(&self) -> Keys<'_, K, V> {
+ Keys {
+ iter: self.entries(),
+ }
+ }
+
+ /// Returns an iterator over the values in the map.
+ ///
+ /// Values are returned in the same order in which they were defined.
+ pub fn values(&self) -> Values<'_, K, V> {
+ Values {
+ iter: self.entries(),
+ }
+ }
+}
+
+impl<'a, K, V> IntoIterator for &'a OrderedMap<K, V> {
+ type Item = (&'a K, &'a V);
+ type IntoIter = Entries<'a, K, V>;
+
+ fn into_iter(self) -> Entries<'a, K, V> {
+ self.entries()
+ }
+}
+
+/// An iterator over the entries in a `OrderedMap`.
+pub struct Entries<'a, K, V> {
+ iter: slice::Iter<'a, (K, V)>,
+}
+
+impl<'a, K, V> Clone for Entries<'a, K, V> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Self {
+ iter: self.iter.clone(),
+ }
+ }
+}
+
+impl<'a, K, V> fmt::Debug for Entries<'a, K, V>
+where
+ K: fmt::Debug,
+ V: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_list().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, K, V> Iterator for Entries<'a, K, V> {
+ type Item = (&'a K, &'a V);
+
+ fn next(&mut self) -> Option<(&'a K, &'a V)> {
+ self.iter.next().map(|e| (&e.0, &e.1))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, K, V> DoubleEndedIterator for Entries<'a, K, V> {
+ fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
+ self.iter.next_back().map(|e| (&e.0, &e.1))
+ }
+}
+
+impl<'a, K, V> ExactSizeIterator for Entries<'a, K, V> {}
+
+impl<'a, K, V> FusedIterator for Entries<'a, K, V> {}
+
+/// An iterator over the keys in a `OrderedMap`.
+pub struct Keys<'a, K, V> {
+ iter: Entries<'a, K, V>,
+}
+
+impl<'a, K, V> Clone for Keys<'a, K, V> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Self {
+ iter: self.iter.clone(),
+ }
+ }
+}
+
+impl<'a, K, V> fmt::Debug for Keys<'a, K, V>
+where
+ K: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_list().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, K, V> Iterator for Keys<'a, K, V> {
+ type Item = &'a K;
+
+ fn next(&mut self) -> Option<&'a K> {
+ self.iter.next().map(|e| e.0)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
+ fn next_back(&mut self) -> Option<&'a K> {
+ self.iter.next_back().map(|e| e.0)
+ }
+}
+
+impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {}
+
+impl<'a, K, V> FusedIterator for Keys<'a, K, V> {}
+
+/// An iterator over the values in a `OrderedMap`.
+pub struct Values<'a, K, V> {
+ iter: Entries<'a, K, V>,
+}
+
+impl<'a, K, V> Clone for Values<'a, K, V> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Self {
+ iter: self.iter.clone(),
+ }
+ }
+}
+
+impl<'a, K, V> fmt::Debug for Values<'a, K, V>
+where
+ V: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_list().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, K, V> Iterator for Values<'a, K, V> {
+ type Item = &'a V;
+
+ fn next(&mut self) -> Option<&'a V> {
+ self.iter.next().map(|e| e.1)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
+ fn next_back(&mut self) -> Option<&'a V> {
+ self.iter.next_back().map(|e| e.1)
+ }
+}
+
+impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}
+
+impl<'a, K, V> FusedIterator for Values<'a, K, V> {}
diff --git a/vendor/phf/src/ordered_set.rs b/vendor/phf/src/ordered_set.rs
new file mode 100644
index 000000000..e85d45711
--- /dev/null
+++ b/vendor/phf/src/ordered_set.rs
@@ -0,0 +1,170 @@
+//! An order-preserving immutable set constructed at compile time.
+use crate::{ordered_map, OrderedMap, PhfHash};
+use core::fmt;
+use core::iter::FusedIterator;
+use core::iter::IntoIterator;
+use phf_shared::PhfBorrow;
+
+/// An order-preserving immutable set constructed at compile time.
+///
+/// Unlike a `Set`, iteration order is guaranteed to match the definition
+/// order.
+///
+/// ## Note
+///
+/// The fields of this struct are public so that they may be initialized by the
+/// `phf_ordered_set!` macro and code generation. They are subject to change at
+/// any time and should never be accessed directly.
+pub struct OrderedSet<T: 'static> {
+ #[doc(hidden)]
+ pub map: OrderedMap<T, ()>,
+}
+
+impl<T> fmt::Debug for OrderedSet<T>
+where
+ T: fmt::Debug,
+{
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_set().entries(self).finish()
+ }
+}
+
+impl<T> OrderedSet<T> {
+ /// Returns the number of elements in the `OrderedSet`.
+ #[inline]
+ pub const fn len(&self) -> usize {
+ self.map.len()
+ }
+
+ /// Returns true if the `OrderedSet` contains no elements.
+ #[inline]
+ pub const fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
+ /// Returns a reference to the set's internal static instance of the given
+ /// key.
+ ///
+ /// This can be useful for interning schemes.
+ pub fn get_key<U: ?Sized>(&self, key: &U) -> Option<&T>
+ where
+ U: Eq + PhfHash,
+ T: PhfBorrow<U>,
+ {
+ self.map.get_key(key)
+ }
+
+ /// Returns the index of the key within the list used to initialize
+ /// the ordered set.
+ pub fn get_index<U: ?Sized>(&self, key: &U) -> Option<usize>
+ where
+ U: Eq + PhfHash,
+ T: PhfBorrow<U>,
+ {
+ self.map.get_index(key)
+ }
+
+ /// Returns a reference to the key at an index
+ /// within the list used to initialize the ordered set. See `.get_index(key)`.
+ pub fn index(&self, index: usize) -> Option<&T> {
+ self.map.index(index).map(|(k, &())| k)
+ }
+
+ /// Returns true if `value` is in the `OrderedSet`.
+ pub fn contains<U: ?Sized>(&self, value: &U) -> bool
+ where
+ U: Eq + PhfHash,
+ T: PhfBorrow<U>,
+ {
+ self.map.contains_key(value)
+ }
+
+ /// Returns an iterator over the values in the set.
+ ///
+ /// Values are returned in the same order in which they were defined.
+ pub fn iter(&self) -> Iter<'_, T> {
+ Iter {
+ iter: self.map.keys(),
+ }
+ }
+}
+
+impl<T> OrderedSet<T>
+where
+ T: Eq + PhfHash + PhfBorrow<T>,
+{
+ /// Returns true if `other` shares no elements with `self`.
+ #[inline]
+ pub fn is_disjoint(&self, other: &OrderedSet<T>) -> bool {
+ !self.iter().any(|value| other.contains(value))
+ }
+
+ /// Returns true if `other` contains all values in `self`.
+ #[inline]
+ pub fn is_subset(&self, other: &OrderedSet<T>) -> bool {
+ self.iter().all(|value| other.contains(value))
+ }
+
+ /// Returns true if `self` contains all values in `other`.
+ #[inline]
+ pub fn is_superset(&self, other: &OrderedSet<T>) -> bool {
+ other.is_subset(self)
+ }
+}
+
+impl<'a, T> IntoIterator for &'a OrderedSet<T> {
+ type Item = &'a T;
+ type IntoIter = Iter<'a, T>;
+
+ fn into_iter(self) -> Iter<'a, T> {
+ self.iter()
+ }
+}
+
+/// An iterator over the values in a `OrderedSet`.
+pub struct Iter<'a, T> {
+ iter: ordered_map::Keys<'a, T, ()>,
+}
+
+impl<'a, T> Clone for Iter<'a, T> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Self {
+ iter: self.iter.clone(),
+ }
+ }
+}
+
+impl<'a, T> fmt::Debug for Iter<'a, T>
+where
+ T: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_list().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, T> Iterator for Iter<'a, T> {
+ type Item = &'a T;
+
+ #[inline]
+ fn next(&mut self) -> Option<&'a T> {
+ self.iter.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<&'a T> {
+ self.iter.next_back()
+ }
+}
+
+impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
+
+impl<'a, T> FusedIterator for Iter<'a, T> {}
diff --git a/vendor/phf/src/set.rs b/vendor/phf/src/set.rs
new file mode 100644
index 000000000..d9fdd5bb2
--- /dev/null
+++ b/vendor/phf/src/set.rs
@@ -0,0 +1,147 @@
+//! An immutable set constructed at compile time.
+use core::fmt;
+use core::iter::FusedIterator;
+use core::iter::IntoIterator;
+
+use phf_shared::{PhfBorrow, PhfHash};
+
+use crate::{map, Map};
+
+/// An immutable set constructed at compile time.
+///
+/// ## Note
+///
+/// The fields of this struct are public so that they may be initialized by the
+/// `phf_set!` macro and code generation. They are subject to change at any
+/// time and should never be accessed directly.
+pub struct Set<T: 'static> {
+ #[doc(hidden)]
+ pub map: Map<T, ()>,
+}
+
+impl<T> fmt::Debug for Set<T>
+where
+ T: fmt::Debug,
+{
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.debug_set().entries(self).finish()
+ }
+}
+
+impl<T> Set<T> {
+ /// Returns the number of elements in the `Set`.
+ #[inline]
+ pub const fn len(&self) -> usize {
+ self.map.len()
+ }
+
+ /// Returns true if the `Set` contains no elements.
+ #[inline]
+ pub const fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
+ /// Returns a reference to the set's internal static instance of the given
+ /// key.
+ ///
+ /// This can be useful for interning schemes.
+ pub fn get_key<U: ?Sized>(&self, key: &U) -> Option<&T>
+ where
+ U: Eq + PhfHash,
+ T: PhfBorrow<U>,
+ {
+ self.map.get_key(key)
+ }
+
+ /// Returns true if `value` is in the `Set`.
+ pub fn contains<U: ?Sized>(&self, value: &U) -> bool
+ where
+ U: Eq + PhfHash,
+ T: PhfBorrow<U>,
+ {
+ self.map.contains_key(value)
+ }
+
+ /// Returns an iterator over the values in the set.
+ ///
+ /// Values are returned in an arbitrary but fixed order.
+ pub fn iter(&self) -> Iter<'_, T> {
+ Iter {
+ iter: self.map.keys(),
+ }
+ }
+}
+
+impl<T> Set<T>
+where
+ T: Eq + PhfHash + PhfBorrow<T>,
+{
+ /// Returns true if `other` shares no elements with `self`.
+ pub fn is_disjoint(&self, other: &Set<T>) -> bool {
+ !self.iter().any(|value| other.contains(value))
+ }
+
+ /// Returns true if `other` contains all values in `self`.
+ pub fn is_subset(&self, other: &Set<T>) -> bool {
+ self.iter().all(|value| other.contains(value))
+ }
+
+ /// Returns true if `self` contains all values in `other`.
+ pub fn is_superset(&self, other: &Set<T>) -> bool {
+ other.is_subset(self)
+ }
+}
+
+impl<'a, T> IntoIterator for &'a Set<T> {
+ type Item = &'a T;
+ type IntoIter = Iter<'a, T>;
+
+ fn into_iter(self) -> Iter<'a, T> {
+ self.iter()
+ }
+}
+
+/// An iterator over the values in a `Set`.
+pub struct Iter<'a, T: 'static> {
+ iter: map::Keys<'a, T, ()>,
+}
+
+impl<'a, T> Clone for Iter<'a, T> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Self {
+ iter: self.iter.clone(),
+ }
+ }
+}
+
+impl<'a, T> fmt::Debug for Iter<'a, T>
+where
+ T: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_list().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, T> Iterator for Iter<'a, T> {
+ type Item = &'a T;
+
+ fn next(&mut self) -> Option<&'a T> {
+ self.iter.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
+ fn next_back(&mut self) -> Option<&'a T> {
+ self.iter.next_back()
+ }
+}
+
+impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
+
+impl<'a, T> FusedIterator for Iter<'a, T> {}
diff --git a/vendor/phf_codegen/.cargo-checksum.json b/vendor/phf_codegen/.cargo-checksum.json
new file mode 100644
index 000000000..1f6ffe9fc
--- /dev/null
+++ b/vendor/phf_codegen/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"f6fd52523100ca5655e0326407e2e4b7c9df947ab55a2d1079b424ada242e9cc","src/lib.rs":"26542892e9f9aac772fe1c37b5f5d8119ec64db91bf8c4f8b018c30cdff33ee8"},"package":"4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd"} \ No newline at end of file
diff --git a/vendor/phf_codegen/Cargo.toml b/vendor/phf_codegen/Cargo.toml
new file mode 100644
index 000000000..c22369fb2
--- /dev/null
+++ b/vendor/phf_codegen/Cargo.toml
@@ -0,0 +1,25 @@
+# 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 are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "phf_codegen"
+version = "0.10.0"
+authors = ["Steven Fackler <sfackler@gmail.com>"]
+description = "Codegen library for PHF types"
+readme = "../README.md"
+license = "MIT"
+repository = "https://github.com/sfackler/rust-phf"
+[dependencies.phf_generator]
+version = "0.10.0"
+
+[dependencies.phf_shared]
+version = "0.10.0"
diff --git a/vendor/phf_codegen/src/lib.rs b/vendor/phf_codegen/src/lib.rs
new file mode 100644
index 000000000..dfcf6ed0e
--- /dev/null
+++ b/vendor/phf_codegen/src/lib.rs
@@ -0,0 +1,486 @@
+//! A set of builders to generate Rust source for PHF data structures at
+//! compile time.
+//!
+//! The provided builders are intended to be used in a Cargo build script to
+//! generate a Rust source file that will be included in a library at build
+//! time.
+//!
+//! # Examples
+//!
+//! build.rs:
+//!
+//! ```rust,no_run
+//! use std::env;
+//! use std::fs::File;
+//! use std::io::{BufWriter, Write};
+//! use std::path::Path;
+//!
+//! fn main() {
+//! let path = Path::new(&env::var("OUT_DIR").unwrap()).join("codegen.rs");
+//! let mut file = BufWriter::new(File::create(&path).unwrap());
+//!
+//! writeln!(
+//! &mut file,
+//! "static KEYWORDS: phf::Map<&'static str, Keyword> = \n{};\n",
+//! phf_codegen::Map::new()
+//! .entry("loop", "Keyword::Loop")
+//! .entry("continue", "Keyword::Continue")
+//! .entry("break", "Keyword::Break")
+//! .entry("fn", "Keyword::Fn")
+//! .entry("extern", "Keyword::Extern")
+//! .build()
+//! ).unwrap();
+//! }
+//! ```
+//!
+//! lib.rs:
+//!
+//! ```ignore
+//! #[derive(Clone)]
+//! enum Keyword {
+//! Loop,
+//! Continue,
+//! Break,
+//! Fn,
+//! Extern,
+//! }
+//!
+//! include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
+//!
+//! pub fn parse_keyword(keyword: &str) -> Option<Keyword> {
+//! KEYWORDS.get(keyword).cloned()
+//! }
+//! ```
+//!
+//! ##### Byte-String Keys
+//! Byte strings by default produce references to fixed-size arrays; the compiler needs a hint
+//! to coerce them to slices:
+//!
+//! build.rs:
+//!
+//! ```rust,no_run
+//! use std::env;
+//! use std::fs::File;
+//! use std::io::{BufWriter, Write};
+//! use std::path::Path;
+//!
+//! fn main() {
+//! let path = Path::new(&env::var("OUT_DIR").unwrap()).join("codegen.rs");
+//! let mut file = BufWriter::new(File::create(&path).unwrap());
+//!
+//! writeln!(
+//! &mut file,
+//! "static KEYWORDS: phf::Map<&'static [u8], Keyword> = \n{};\n",
+//! phf_codegen::Map::<&[u8]>::new()
+//! .entry(b"loop", "Keyword::Loop")
+//! .entry(b"continue", "Keyword::Continue")
+//! .entry(b"break", "Keyword::Break")
+//! .entry(b"fn", "Keyword::Fn")
+//! .entry(b"extern", "Keyword::Extern")
+//! .build()
+//! ).unwrap();
+//! }
+//! ```
+//!
+//! lib.rs:
+//!
+//! ```rust,ignore
+//! #[derive(Clone)]
+//! enum Keyword {
+//! Loop,
+//! Continue,
+//! Break,
+//! Fn,
+//! Extern,
+//! }
+//!
+//! include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
+//!
+//! pub fn parse_keyword(keyword: &[u8]) -> Option<Keyword> {
+//! KEYWORDS.get(keyword).cloned()
+//! }
+//! ```
+//!
+//! # Note
+//!
+//! The compiler's stack will overflow when processing extremely long method
+//! chains (500+ calls). When generating large PHF data structures, consider
+//! looping over the entries or making each call a separate statement:
+//!
+//! ```rust
+//! let entries = [("hello", "1"), ("world", "2")];
+//!
+//! let mut builder = phf_codegen::Map::new();
+//! for &(key, value) in &entries {
+//! builder.entry(key, value);
+//! }
+//! // ...
+//! ```
+//!
+//! ```rust
+//! let mut builder = phf_codegen::Map::new();
+//! builder.entry("hello", "1");
+//! builder.entry("world", "2");
+//! // ...
+//! ```
+#![doc(html_root_url = "https://docs.rs/phf_codegen/0.9")]
+
+use phf_shared::{FmtConst, PhfHash};
+use std::collections::HashSet;
+use std::fmt;
+use std::hash::Hash;
+
+use phf_generator::HashState;
+
+struct Delegate<T>(T);
+
+impl<T: FmtConst> fmt::Display for Delegate<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.0.fmt_const(f)
+ }
+}
+
+/// A builder for the `phf::Map` type.
+pub struct Map<K> {
+ keys: Vec<K>,
+ values: Vec<String>,
+ path: String,
+}
+
+impl<K: Hash + PhfHash + Eq + FmtConst> Map<K> {
+ /// Creates a new `phf::Map` builder.
+ pub fn new() -> Map<K> {
+ // FIXME rust#27438
+ //
+ // On Windows/MSVC there are major problems with the handling of dllimport.
+ // Here, because downstream build scripts only invoke generics from phf_codegen,
+ // the linker ends up throwing a way a bunch of static symbols we actually need.
+ // This works around the problem, assuming that all clients call `Map::new` by
+ // calling a non-generic function.
+ fn noop_fix_for_27438() {}
+ noop_fix_for_27438();
+
+ Map {
+ keys: vec![],
+ values: vec![],
+ path: String::from("::phf"),
+ }
+ }
+
+ /// Set the path to the `phf` crate from the global namespace
+ pub fn phf_path(&mut self, path: &str) -> &mut Map<K> {
+ self.path = path.to_owned();
+ self
+ }
+
+ /// Adds an entry to the builder.
+ ///
+ /// `value` will be written exactly as provided in the constructed source.
+ pub fn entry(&mut self, key: K, value: &str) -> &mut Map<K> {
+ self.keys.push(key);
+ self.values.push(value.to_owned());
+ self
+ }
+
+ /// Calculate the hash parameters and return a struct implementing
+ /// [`Display`](::std::fmt::Display) which will print the constructed `phf::Map`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if there are any duplicate keys.
+ pub fn build(&self) -> DisplayMap<'_, K> {
+ let mut set = HashSet::new();
+ for key in &self.keys {
+ if !set.insert(key) {
+ panic!("duplicate key `{}`", Delegate(key));
+ }
+ }
+
+ let state = phf_generator::generate_hash(&self.keys);
+
+ DisplayMap {
+ path: &self.path,
+ keys: &self.keys,
+ values: &self.values,
+ state,
+ }
+ }
+}
+
+/// An adapter for printing a [`Map`](Map).
+pub struct DisplayMap<'a, K> {
+ path: &'a str,
+ state: HashState,
+ keys: &'a [K],
+ values: &'a [String],
+}
+
+impl<'a, K: FmtConst + 'a> fmt::Display for DisplayMap<'a, K> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // funky formatting here for nice output
+ write!(
+ f,
+ "{}::Map {{
+ key: {:?},
+ disps: &[",
+ self.path, self.state.key
+ )?;
+
+ // write map displacements
+ for &(d1, d2) in &self.state.disps {
+ write!(
+ f,
+ "
+ ({}, {}),",
+ d1, d2
+ )?;
+ }
+
+ write!(
+ f,
+ "
+ ],
+ entries: &[",
+ )?;
+
+ // write map entries
+ for &idx in &self.state.map {
+ write!(
+ f,
+ "
+ ({}, {}),",
+ Delegate(&self.keys[idx]),
+ &self.values[idx]
+ )?;
+ }
+
+ write!(
+ f,
+ "
+ ],
+}}"
+ )
+ }
+}
+
+/// A builder for the `phf::Set` type.
+pub struct Set<T> {
+ map: Map<T>,
+}
+
+impl<T: Hash + PhfHash + Eq + FmtConst> Set<T> {
+ /// Constructs a new `phf::Set` builder.
+ pub fn new() -> Set<T> {
+ Set { map: Map::new() }
+ }
+
+ /// Set the path to the `phf` crate from the global namespace
+ pub fn phf_path(&mut self, path: &str) -> &mut Set<T> {
+ self.map.phf_path(path);
+ self
+ }
+
+ /// Adds an entry to the builder.
+ pub fn entry(&mut self, entry: T) -> &mut Set<T> {
+ self.map.entry(entry, "()");
+ self
+ }
+
+ /// Calculate the hash parameters and return a struct implementing
+ /// [`Display`](::std::fmt::Display) which will print the constructed `phf::Set`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if there are any duplicate keys.
+ pub fn build(&self) -> DisplaySet<'_, T> {
+ DisplaySet {
+ inner: self.map.build(),
+ }
+ }
+}
+
+/// An adapter for printing a [`Set`](Set).
+pub struct DisplaySet<'a, T> {
+ inner: DisplayMap<'a, T>,
+}
+
+impl<'a, T: FmtConst + 'a> fmt::Display for DisplaySet<'a, T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}::Set {{ map: {} }}", self.inner.path, self.inner)
+ }
+}
+
+/// A builder for the `phf::OrderedMap` type.
+pub struct OrderedMap<K> {
+ keys: Vec<K>,
+ values: Vec<String>,
+ path: String,
+}
+
+impl<K: Hash + PhfHash + Eq + FmtConst> OrderedMap<K> {
+ /// Constructs a enw `phf::OrderedMap` builder.
+ pub fn new() -> OrderedMap<K> {
+ OrderedMap {
+ keys: vec![],
+ values: vec![],
+ path: String::from("::phf"),
+ }
+ }
+
+ /// Set the path to the `phf` crate from the global namespace
+ pub fn phf_path(&mut self, path: &str) -> &mut OrderedMap<K> {
+ self.path = path.to_owned();
+ self
+ }
+
+ /// Adds an entry to the builder.
+ ///
+ /// `value` will be written exactly as provided in the constructed source.
+ pub fn entry(&mut self, key: K, value: &str) -> &mut OrderedMap<K> {
+ self.keys.push(key);
+ self.values.push(value.to_owned());
+ self
+ }
+
+ /// Calculate the hash parameters and return a struct implementing
+ /// [`Display`](::std::fmt::Display) which will print the constructed
+ /// `phf::OrderedMap`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if there are any duplicate keys.
+ pub fn build(&self) -> DisplayOrderedMap<'_, K> {
+ let mut set = HashSet::new();
+ for key in &self.keys {
+ if !set.insert(key) {
+ panic!("duplicate key `{}`", Delegate(key));
+ }
+ }
+
+ let state = phf_generator::generate_hash(&self.keys);
+
+ DisplayOrderedMap {
+ path: &self.path,
+ state,
+ keys: &self.keys,
+ values: &self.values,
+ }
+ }
+}
+
+/// An adapter for printing a [`OrderedMap`](OrderedMap).
+pub struct DisplayOrderedMap<'a, K> {
+ path: &'a str,
+ state: HashState,
+ keys: &'a [K],
+ values: &'a [String],
+}
+
+impl<'a, K: FmtConst + 'a> fmt::Display for DisplayOrderedMap<'a, K> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "{}::OrderedMap {{
+ key: {:?},
+ disps: &[",
+ self.path, self.state.key
+ )?;
+ for &(d1, d2) in &self.state.disps {
+ write!(
+ f,
+ "
+ ({}, {}),",
+ d1, d2
+ )?;
+ }
+ write!(
+ f,
+ "
+ ],
+ idxs: &[",
+ )?;
+ for &idx in &self.state.map {
+ write!(
+ f,
+ "
+ {},",
+ idx
+ )?;
+ }
+ write!(
+ f,
+ "
+ ],
+ entries: &[",
+ )?;
+ for (key, value) in self.keys.iter().zip(self.values.iter()) {
+ write!(
+ f,
+ "
+ ({}, {}),",
+ Delegate(key),
+ value
+ )?;
+ }
+ write!(
+ f,
+ "
+ ],
+}}"
+ )
+ }
+}
+
+/// A builder for the `phf::OrderedSet` type.
+pub struct OrderedSet<T> {
+ map: OrderedMap<T>,
+}
+
+impl<T: Hash + PhfHash + Eq + FmtConst> OrderedSet<T> {
+ /// Constructs a new `phf::OrderedSet` builder.
+ pub fn new() -> OrderedSet<T> {
+ OrderedSet {
+ map: OrderedMap::new(),
+ }
+ }
+
+ /// Set the path to the `phf` crate from the global namespace
+ pub fn phf_path(&mut self, path: &str) -> &mut OrderedSet<T> {
+ self.map.phf_path(path);
+ self
+ }
+
+ /// Adds an entry to the builder.
+ pub fn entry(&mut self, entry: T) -> &mut OrderedSet<T> {
+ self.map.entry(entry, "()");
+ self
+ }
+
+ /// Calculate the hash parameters and return a struct implementing
+ /// [`Display`](::std::fmt::Display) which will print the constructed
+ /// `phf::OrderedSet`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if there are any duplicate keys.
+ pub fn build(&self) -> DisplayOrderedSet<'_, T> {
+ DisplayOrderedSet {
+ inner: self.map.build(),
+ }
+ }
+}
+
+/// An adapter for printing a [`OrderedSet`](OrderedSet).
+pub struct DisplayOrderedSet<'a, T> {
+ inner: DisplayOrderedMap<'a, T>,
+}
+
+impl<'a, T: FmtConst + 'a> fmt::Display for DisplayOrderedSet<'a, T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "{}::OrderedSet {{ map: {} }}",
+ self.inner.path, self.inner
+ )
+ }
+}
diff --git a/vendor/phf_generator/.cargo-checksum.json b/vendor/phf_generator/.cargo-checksum.json
new file mode 100644
index 000000000..da32ef167
--- /dev/null
+++ b/vendor/phf_generator/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.lock":"78ce14c16f470a167be59026946ff3caf139ecbad133e0ff01732d5f8702e2ce","Cargo.toml":"46412745915006724fdfa342f9804013efa4b1413564fcff0dd4d795404018b2","benches/benches.rs":"5d8dc7df14d19d46554908c66832e7075a6ae5f900b491e4f246ed34762ffcc1","src/bin/gen_hash_test.rs":"6837aa742812fb5f23e014a006d54ee9ad92b42b1ee8461e848e53b29e54c24f","src/lib.rs":"18ef26903499d8520e4c22a30fec95e1275909490f3b5d09c326c1d85fa911e7"},"package":"5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"} \ No newline at end of file
diff --git a/vendor/phf_generator/Cargo.lock b/vendor/phf_generator/Cargo.lock
new file mode 100644
index 000000000..1e2faa18a
--- /dev/null
+++ b/vendor/phf_generator/Cargo.lock
@@ -0,0 +1,679 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+
+[[package]]
+name = "bitflags"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+
+[[package]]
+name = "bstr"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
+dependencies = [
+ "lazy_static",
+ "memchr",
+ "regex-automata",
+ "serde",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
+
+[[package]]
+name = "cast"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
+dependencies = [
+ "rustc_version",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clap"
+version = "2.33.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
+dependencies = [
+ "bitflags",
+ "textwrap",
+ "unicode-width",
+]
+
+[[package]]
+name = "criterion"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23"
+dependencies = [
+ "atty",
+ "cast",
+ "clap",
+ "criterion-plot",
+ "csv",
+ "itertools",
+ "lazy_static",
+ "num-traits",
+ "oorandom",
+ "plotters",
+ "rayon",
+ "regex",
+ "serde",
+ "serde_cbor",
+ "serde_derive",
+ "serde_json",
+ "tinytemplate",
+ "walkdir",
+]
+
+[[package]]
+name = "criterion-plot"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57"
+dependencies = [
+ "cast",
+ "itertools",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
+dependencies = [
+ "cfg-if",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+ "lazy_static",
+ "memoffset",
+ "scopeguard",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
+dependencies = [
+ "cfg-if",
+ "lazy_static",
+]
+
+[[package]]
+name = "csv"
+version = "1.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
+dependencies = [
+ "bstr",
+ "csv-core",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "csv-core"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "either"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+
+[[package]]
+name = "getrandom"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "half"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
+
+[[package]]
+name = "js-sys"
+version = "0.3.52"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce791b7ca6638aae45be056e068fc756d871eb3b3b10b8efa62d1c9cec616752"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
+
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
+
+[[package]]
+name = "memoffset"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "oorandom"
+version = "11.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
+
+[[package]]
+name = "phf_generator"
+version = "0.10.0"
+dependencies = [
+ "criterion",
+ "phf_shared",
+ "rand",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
+name = "plotters"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
+dependencies = [
+ "num-traits",
+ "plotters-backend",
+ "plotters-svg",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "plotters-backend"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c"
+
+[[package]]
+name = "plotters-svg"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9"
+dependencies = [
+ "plotters-backend",
+]
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+ "rand_hc",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
+name = "rayon"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
+dependencies = [
+ "autocfg",
+ "crossbeam-deque",
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
+dependencies = [
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-utils",
+ "lazy_static",
+ "num_cpus",
+]
+
+[[package]]
+name = "regex"
+version = "1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+dependencies = [
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "semver"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
+
+[[package]]
+name = "serde"
+version = "1.0.127"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
+
+[[package]]
+name = "serde_cbor"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
+dependencies = [
+ "half",
+ "serde",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.127"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "siphasher"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1"
+
+[[package]]
+name = "syn"
+version = "1.0.74"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+dependencies = [
+ "unicode-width",
+]
+
+[[package]]
+name = "tinytemplate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasi"
+version = "0.10.2+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b608ecc8f4198fe8680e2ed18eccab5f0cd4caaf3d83516fa5fb2e927fda2586"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "580aa3a91a63d23aac5b6b267e2d13cb4f363e31dce6c352fca4752ae12e479f"
+dependencies = [
+ "bumpalo",
+ "lazy_static",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "171ebf0ed9e1458810dfcb31f2e766ad6b3a89dbda42d8901f2b268277e5f09c"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c2657dd393f03aa2a659c25c6ae18a13a4048cebd220e147933ea837efc589f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e0c4a743a309662d45f4ede961d7afa4ba4131a59a639f29b0069c3798bbcc2"
+
+[[package]]
+name = "web-sys"
+version = "0.3.52"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01c70a82d842c9979078c772d4a1344685045f1a5628f677c2b2eab4dd7d2696"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/vendor/phf_generator/Cargo.toml b/vendor/phf_generator/Cargo.toml
new file mode 100644
index 000000000..53394ab30
--- /dev/null
+++ b/vendor/phf_generator/Cargo.toml
@@ -0,0 +1,40 @@
+# 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 are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "phf_generator"
+version = "0.10.0"
+authors = ["Steven Fackler <sfackler@gmail.com>"]
+description = "PHF generation logic"
+license = "MIT"
+repository = "https://github.com/sfackler/rust-phf"
+
+[[bin]]
+name = "gen_hash_test"
+required-features = ["criterion"]
+
+[[bench]]
+name = "benches"
+harness = false
+[dependencies.criterion]
+version = "=0.3.4"
+optional = true
+
+[dependencies.phf_shared]
+version = "0.10.0"
+default-features = false
+
+[dependencies.rand]
+version = "0.8"
+features = ["small_rng"]
+[dev-dependencies.criterion]
+version = "=0.3.4"
diff --git a/vendor/phf_generator/benches/benches.rs b/vendor/phf_generator/benches/benches.rs
new file mode 100644
index 000000000..179c8627b
--- /dev/null
+++ b/vendor/phf_generator/benches/benches.rs
@@ -0,0 +1,58 @@
+use criterion::measurement::Measurement;
+use criterion::{criterion_group, criterion_main, Bencher, BenchmarkId, Criterion};
+
+use rand::distributions::Standard;
+use rand::rngs::SmallRng;
+use rand::{Rng, SeedableRng};
+
+use phf_generator::generate_hash;
+
+fn gen_vec(len: usize) -> Vec<u64> {
+ SmallRng::seed_from_u64(0xAAAAAAAAAAAAAAAA)
+ .sample_iter(Standard)
+ .take(len)
+ .collect()
+}
+
+fn bench_hash<M: Measurement>(b: &mut Bencher<M>, len: &usize) {
+ let vec = gen_vec(*len);
+ b.iter(|| generate_hash(&vec))
+}
+
+fn gen_hash_small(c: &mut Criterion) {
+ let sizes = vec![0, 1, 2, 5, 10, 25, 50, 75];
+ for size in &sizes {
+ c.bench_with_input(BenchmarkId::new("gen_hash_small", *size), size, bench_hash);
+ }
+}
+
+fn gen_hash_med(c: &mut Criterion) {
+ let sizes = vec![100, 250, 500, 1000, 2500, 5000, 7500];
+ for size in &sizes {
+ c.bench_with_input(BenchmarkId::new("gen_hash_medium", *size), size, bench_hash);
+ }
+}
+
+fn gen_hash_large(c: &mut Criterion) {
+ let sizes = vec![10_000, 25_000, 50_000, 75_000];
+ for size in &sizes {
+ c.bench_with_input(BenchmarkId::new("gen_hash_large", *size), size, bench_hash);
+ }
+}
+
+fn gen_hash_xlarge(c: &mut Criterion) {
+ let sizes = vec![100_000, 250_000, 500_000, 750_000, 1_000_000];
+ for size in &sizes {
+ c.bench_with_input(BenchmarkId::new("gen_hash_xlarge", *size), size, bench_hash);
+ }
+}
+
+criterion_group!(
+ benches,
+ gen_hash_small,
+ gen_hash_med,
+ gen_hash_large,
+ gen_hash_xlarge
+);
+
+criterion_main!(benches);
diff --git a/vendor/phf_generator/src/bin/gen_hash_test.rs b/vendor/phf_generator/src/bin/gen_hash_test.rs
new file mode 100644
index 000000000..2e1fbec45
--- /dev/null
+++ b/vendor/phf_generator/src/bin/gen_hash_test.rs
@@ -0,0 +1,20 @@
+use criterion::*;
+
+use rand::distributions::Alphanumeric;
+use rand::rngs::SmallRng;
+use rand::{Rng, SeedableRng};
+
+use phf_generator::generate_hash;
+
+fn gen_vec(len: usize) -> Vec<String> {
+ let mut rng = SmallRng::seed_from_u64(0xAAAAAAAAAAAAAAAA).sample_iter(Alphanumeric);
+
+ (0..len)
+ .map(move |_| rng.by_ref().take(64).collect::<String>())
+ .collect()
+}
+
+fn main() {
+ let data = black_box(gen_vec(1_000_000));
+ black_box(generate_hash(&data));
+}
diff --git a/vendor/phf_generator/src/lib.rs b/vendor/phf_generator/src/lib.rs
new file mode 100644
index 000000000..6c848ce5a
--- /dev/null
+++ b/vendor/phf_generator/src/lib.rs
@@ -0,0 +1,105 @@
+#![doc(html_root_url = "https://docs.rs/phf_generator/0.9")]
+use phf_shared::{HashKey, PhfHash};
+use rand::distributions::Standard;
+use rand::rngs::SmallRng;
+use rand::{Rng, SeedableRng};
+
+const DEFAULT_LAMBDA: usize = 5;
+
+const FIXED_SEED: u64 = 1234567890;
+
+pub struct HashState {
+ pub key: HashKey,
+ pub disps: Vec<(u32, u32)>,
+ pub map: Vec<usize>,
+}
+
+pub fn generate_hash<H: PhfHash>(entries: &[H]) -> HashState {
+ SmallRng::seed_from_u64(FIXED_SEED)
+ .sample_iter(Standard)
+ .find_map(|key| try_generate_hash(entries, key))
+ .expect("failed to solve PHF")
+}
+
+fn try_generate_hash<H: PhfHash>(entries: &[H], key: HashKey) -> Option<HashState> {
+ struct Bucket {
+ idx: usize,
+ keys: Vec<usize>,
+ }
+
+ let hashes: Vec<_> = entries
+ .iter()
+ .map(|entry| phf_shared::hash(entry, &key))
+ .collect();
+
+ let buckets_len = (hashes.len() + DEFAULT_LAMBDA - 1) / DEFAULT_LAMBDA;
+ let mut buckets = (0..buckets_len)
+ .map(|i| Bucket {
+ idx: i,
+ keys: vec![],
+ })
+ .collect::<Vec<_>>();
+
+ for (i, hash) in hashes.iter().enumerate() {
+ buckets[(hash.g % (buckets_len as u32)) as usize]
+ .keys
+ .push(i);
+ }
+
+ // Sort descending
+ buckets.sort_by(|a, b| a.keys.len().cmp(&b.keys.len()).reverse());
+
+ let table_len = hashes.len();
+ let mut map = vec![None; table_len];
+ let mut disps = vec![(0u32, 0u32); buckets_len];
+
+ // store whether an element from the bucket being placed is
+ // located at a certain position, to allow for efficient overlap
+ // checks. It works by storing the generation in each cell and
+ // each new placement-attempt is a new generation, so you can tell
+ // if this is legitimately full by checking that the generations
+ // are equal. (A u64 is far too large to overflow in a reasonable
+ // time for current hardware.)
+ let mut try_map = vec![0u64; table_len];
+ let mut generation = 0u64;
+
+ // the actual values corresponding to the markers above, as
+ // (index, key) pairs, for adding to the main map once we've
+ // chosen the right disps.
+ let mut values_to_add = vec![];
+
+ 'buckets: for bucket in &buckets {
+ for d1 in 0..(table_len as u32) {
+ 'disps: for d2 in 0..(table_len as u32) {
+ values_to_add.clear();
+ generation += 1;
+
+ for &key in &bucket.keys {
+ let idx = (phf_shared::displace(hashes[key].f1, hashes[key].f2, d1, d2)
+ % (table_len as u32)) as usize;
+ if map[idx].is_some() || try_map[idx] == generation {
+ continue 'disps;
+ }
+ try_map[idx] = generation;
+ values_to_add.push((idx, key));
+ }
+
+ // We've picked a good set of disps
+ disps[bucket.idx] = (d1, d2);
+ for &(idx, key) in &values_to_add {
+ map[idx] = Some(key);
+ }
+ continue 'buckets;
+ }
+ }
+
+ // Unable to find displacements for a bucket
+ return None;
+ }
+
+ Some(HashState {
+ key,
+ disps,
+ map: map.into_iter().map(|i| i.unwrap()).collect(),
+ })
+}
diff --git a/vendor/phf_shared/.cargo-checksum.json b/vendor/phf_shared/.cargo-checksum.json
new file mode 100644
index 000000000..07e0f39a0
--- /dev/null
+++ b/vendor/phf_shared/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"dbcb7cd89d95fb146864c5d665496c1803561d5f7f1eea88c35a699f44375f29","src/lib.rs":"e8975dad7d6d3ed71a6bb3bdbe594f18297451cf25dbe69bb1aca61bed2ad5b5"},"package":"b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"} \ No newline at end of file
diff --git a/vendor/phf_shared/Cargo.toml b/vendor/phf_shared/Cargo.toml
new file mode 100644
index 000000000..86ed69472
--- /dev/null
+++ b/vendor/phf_shared/Cargo.toml
@@ -0,0 +1,39 @@
+# 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 are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "phf_shared"
+version = "0.10.0"
+authors = ["Steven Fackler <sfackler@gmail.com>"]
+description = "Support code shared by PHF libraries"
+license = "MIT"
+repository = "https://github.com/sfackler/rust-phf"
+
+[lib]
+name = "phf_shared"
+path = "src/lib.rs"
+test = false
+[dependencies.siphasher]
+version = "0.3"
+
+[dependencies.uncased]
+version = "0.9.6"
+optional = true
+default-features = false
+
+[dependencies.unicase]
+version = "2.4.0"
+optional = true
+
+[features]
+default = ["std"]
+std = []
diff --git a/vendor/phf_shared/src/lib.rs b/vendor/phf_shared/src/lib.rs
new file mode 100644
index 000000000..79b119a32
--- /dev/null
+++ b/vendor/phf_shared/src/lib.rs
@@ -0,0 +1,421 @@
+#![doc(html_root_url = "https://docs.rs/phf_shared/0.9")]
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#[cfg(feature = "std")]
+extern crate std as core;
+
+use core::fmt;
+use core::hash::{Hash, Hasher};
+use core::num::Wrapping;
+use siphasher::sip128::{Hash128, Hasher128, SipHasher13};
+
+#[non_exhaustive]
+pub struct Hashes {
+ pub g: u32,
+ pub f1: u32,
+ pub f2: u32,
+}
+
+/// A central typedef for hash keys
+///
+/// Makes experimentation easier by only needing to be updated here.
+pub type HashKey = u64;
+
+#[inline]
+pub fn displace(f1: u32, f2: u32, d1: u32, d2: u32) -> u32 {
+ (Wrapping(d2) + Wrapping(f1) * Wrapping(d1) + Wrapping(f2)).0
+}
+
+/// `key` is from `phf_generator::HashState`.
+#[inline]
+pub fn hash<T: ?Sized + PhfHash>(x: &T, key: &HashKey) -> Hashes {
+ let mut hasher = SipHasher13::new_with_keys(0, *key);
+ x.phf_hash(&mut hasher);
+
+ let Hash128 {
+ h1: lower,
+ h2: upper,
+ } = hasher.finish128();
+
+ Hashes {
+ g: (lower >> 32) as u32,
+ f1: lower as u32,
+ f2: upper as u32,
+ }
+}
+
+/// Return an index into `phf_generator::HashState::map`.
+///
+/// * `hash` is from `hash()` in this crate.
+/// * `disps` is from `phf_generator::HashState::disps`.
+/// * `len` is the length of `phf_generator::HashState::map`.
+#[inline]
+pub fn get_index(hashes: &Hashes, disps: &[(u32, u32)], len: usize) -> u32 {
+ let (d1, d2) = disps[(hashes.g % (disps.len() as u32)) as usize];
+ displace(hashes.f1, hashes.f2, d1, d2) % (len as u32)
+}
+
+/// A trait implemented by types which can be used in PHF data structures.
+///
+/// This differs from the standard library's `Hash` trait in that `PhfHash`'s
+/// results must be architecture independent so that hashes will be consistent
+/// between the host and target when cross compiling.
+pub trait PhfHash {
+ /// Feeds the value into the state given, updating the hasher as necessary.
+ fn phf_hash<H: Hasher>(&self, state: &mut H);
+
+ /// Feeds a slice of this type into the state provided.
+ fn phf_hash_slice<H: Hasher>(data: &[Self], state: &mut H)
+ where
+ Self: Sized,
+ {
+ for piece in data {
+ piece.phf_hash(state);
+ }
+ }
+}
+
+/// Trait for printing types with `const` constructors, used by `phf_codegen` and `phf_macros`.
+pub trait FmtConst {
+ /// Print a `const` expression representing this value.
+ fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
+}
+
+/// Identical to `std::borrow::Borrow` except omitting blanket impls to facilitate other
+/// borrowing patterns.
+///
+/// The same semantic requirements apply:
+///
+/// > In particular `Eq`, `Ord` and `Hash` must be equivalent for borrowed and owned values:
+/// `x.borrow() == y.borrow()` should give the same result as `x == y`.
+///
+/// (This crate's API only requires `Eq` and `PhfHash`, however.)
+///
+/// ### Motivation
+/// The conventional signature for lookup methods on collections looks something like this:
+///
+/// ```rust,ignore
+/// impl<K, V> Map<K, V> where K: PhfHash + Eq {
+/// fn get<T: ?Sized>(&self, key: &T) -> Option<&V> where T: PhfHash + Eq, K: Borrow<T> {
+/// ...
+/// }
+/// }
+/// ```
+///
+/// This allows the key type used for lookup to be different than the key stored in the map so for
+/// example you can use `&str` to look up a value in a `Map<String, _>`. However, this runs into
+/// a problem in the case where `T` and `K` are both a `Foo<_>` type constructor but
+/// the contained type is different (even being the same type with different lifetimes).
+///
+/// The main issue for this crate's API is that, with this method signature, you cannot perform a
+/// lookup on a `Map<UniCase<&'static str>, _>` with a `UniCase<&'a str>` where `'a` is not
+/// `'static`; there is no impl of `Borrow` that resolves to
+/// `impl Borrow<UniCase<'a>> for UniCase<&'static str>` and one cannot be added either because of
+/// all the blanket impls.
+///
+/// Instead, this trait is implemented conservatively, without blanket impls, so that impls like
+/// this may be added. This is feasible since the set of types that implement `PhfHash` is
+/// intentionally small.
+///
+/// This likely won't be fixable with specialization alone but will require full support for lattice
+/// impls since we technically want to add overlapping blanket impls.
+pub trait PhfBorrow<B: ?Sized> {
+ /// Convert a reference to `self` to a reference to the borrowed type.
+ fn borrow(&self) -> &B;
+}
+
+/// Create an impl of `FmtConst` delegating to `fmt::Debug` for types that can deal with it.
+///
+/// Ideally with specialization this could be just one default impl and then specialized where
+/// it doesn't apply.
+macro_rules! delegate_debug (
+ ($ty:ty) => {
+ impl FmtConst for $ty {
+ fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:?}", self)
+ }
+ }
+ }
+);
+
+delegate_debug!(str);
+delegate_debug!(char);
+delegate_debug!(u8);
+delegate_debug!(i8);
+delegate_debug!(u16);
+delegate_debug!(i16);
+delegate_debug!(u32);
+delegate_debug!(i32);
+delegate_debug!(u64);
+delegate_debug!(i64);
+delegate_debug!(u128);
+delegate_debug!(i128);
+delegate_debug!(bool);
+
+/// `impl PhfBorrow<T> for T`
+macro_rules! impl_reflexive(
+ ($($t:ty),*) => (
+ $(impl PhfBorrow<$t> for $t {
+ fn borrow(&self) -> &$t {
+ self
+ }
+ })*
+ )
+);
+
+impl_reflexive!(
+ str,
+ char,
+ u8,
+ i8,
+ u16,
+ i16,
+ u32,
+ i32,
+ u64,
+ i64,
+ u128,
+ i128,
+ bool,
+ [u8]
+);
+
+#[cfg(feature = "std")]
+impl PhfBorrow<str> for String {
+ fn borrow(&self) -> &str {
+ self
+ }
+}
+
+#[cfg(feature = "std")]
+impl PhfBorrow<[u8]> for Vec<u8> {
+ fn borrow(&self) -> &[u8] {
+ self
+ }
+}
+
+#[cfg(feature = "std")]
+delegate_debug!(String);
+
+#[cfg(feature = "std")]
+impl PhfHash for String {
+ #[inline]
+ fn phf_hash<H: Hasher>(&self, state: &mut H) {
+ (**self).phf_hash(state)
+ }
+}
+
+#[cfg(feature = "std")]
+impl PhfHash for Vec<u8> {
+ #[inline]
+ fn phf_hash<H: Hasher>(&self, state: &mut H) {
+ (**self).phf_hash(state)
+ }
+}
+
+impl<'a, T: 'a + PhfHash + ?Sized> PhfHash for &'a T {
+ fn phf_hash<H: Hasher>(&self, state: &mut H) {
+ (*self).phf_hash(state)
+ }
+}
+
+impl<'a, T: 'a + FmtConst + ?Sized> FmtConst for &'a T {
+ fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ (*self).fmt_const(f)
+ }
+}
+
+impl<'a> PhfBorrow<str> for &'a str {
+ fn borrow(&self) -> &str {
+ self
+ }
+}
+
+impl<'a> PhfBorrow<[u8]> for &'a [u8] {
+ fn borrow(&self) -> &[u8] {
+ self
+ }
+}
+
+impl PhfHash for str {
+ #[inline]
+ fn phf_hash<H: Hasher>(&self, state: &mut H) {
+ self.as_bytes().phf_hash(state)
+ }
+}
+
+impl PhfHash for [u8] {
+ #[inline]
+ fn phf_hash<H: Hasher>(&self, state: &mut H) {
+ state.write(self);
+ }
+}
+
+impl FmtConst for [u8] {
+ #[inline]
+ fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // slices need a leading reference
+ write!(f, "&{:?}", self)
+ }
+}
+
+#[cfg(feature = "unicase")]
+impl<S> PhfHash for unicase::UniCase<S>
+where
+ unicase::UniCase<S>: Hash,
+{
+ #[inline]
+ fn phf_hash<H: Hasher>(&self, state: &mut H) {
+ self.hash(state)
+ }
+}
+
+#[cfg(feature = "unicase")]
+impl<S> FmtConst for unicase::UniCase<S>
+where
+ S: AsRef<str>,
+{
+ fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ if self.is_ascii() {
+ f.write_str("UniCase::ascii(")?;
+ } else {
+ f.write_str("UniCase::unicode(")?;
+ }
+
+ self.as_ref().fmt_const(f)?;
+ f.write_str(")")
+ }
+}
+
+#[cfg(feature = "unicase")]
+impl<'b, 'a: 'b, S: ?Sized + 'a> PhfBorrow<unicase::UniCase<&'b S>> for unicase::UniCase<&'a S> {
+ fn borrow(&self) -> &unicase::UniCase<&'b S> {
+ self
+ }
+}
+
+#[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(") }")
+ }
+}
+
+#[cfg(feature = "uncased")]
+impl PhfBorrow<uncased::UncasedStr> for &uncased::UncasedStr {
+ fn borrow(&self) -> &uncased::UncasedStr {
+ self
+ }
+}
+
+macro_rules! sip_impl (
+ (le $t:ty) => (
+ impl PhfHash for $t {
+ #[inline]
+ fn phf_hash<H: Hasher>(&self, state: &mut H) {
+ self.to_le().hash(state);
+ }
+ }
+ );
+ ($t:ty) => (
+ impl PhfHash for $t {
+ #[inline]
+ fn phf_hash<H: Hasher>(&self, state: &mut H) {
+ self.hash(state);
+ }
+ }
+ )
+);
+
+sip_impl!(u8);
+sip_impl!(i8);
+sip_impl!(le u16);
+sip_impl!(le i16);
+sip_impl!(le u32);
+sip_impl!(le i32);
+sip_impl!(le u64);
+sip_impl!(le i64);
+sip_impl!(le u128);
+sip_impl!(le i128);
+sip_impl!(bool);
+
+impl PhfHash for char {
+ #[inline]
+ fn phf_hash<H: Hasher>(&self, state: &mut H) {
+ (*self as u32).phf_hash(state)
+ }
+}
+
+// minimize duplicated code since formatting drags in quite a bit
+fn fmt_array(array: &[u8], f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:?}", array)
+}
+
+macro_rules! array_impl (
+ ($t:ty, $n:expr) => (
+ impl PhfHash for [$t; $n] {
+ #[inline]
+ fn phf_hash<H: Hasher>(&self, state: &mut H) {
+ state.write(self);
+ }
+ }
+
+ impl FmtConst for [$t; $n] {
+ fn fmt_const(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt_array(self, f)
+ }
+ }
+
+ impl PhfBorrow<[$t]> for [$t; $n] {
+ fn borrow(&self) -> &[$t] {
+ self
+ }
+ }
+ )
+);
+
+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);