Skip to main content

fnv64_rs/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![cfg_attr(not(feature = "std"), no_std)]
3#![cfg_attr(feature = "nightly", feature(allocator_api))]
4
5//! [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/dante19031999/fnv-rs/tree/main?tab=Apache-2.0-1-ov-file#readme)
6//! [![No Std](https://img.shields.io/badge/no__std-compatible-success.svg)](#)
7//! [![Rust Version](https://img.shields.io/badge/rustc-1.56+-lightgray.svg?logo=rust)](https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html)
8//! [![Cargo Version](https://img.shields.io/crates/v/fnv64-rs.svg)](https://crates.io/crates/fnv64-rs)
9//! [![Documentation](https://docs.rs/fnv64-rs/badge.svg)](https://docs.rs/fnv64-rs)
10//!
11//! # FNV Hashing
12//!
13//! An implementation of the [Fowler–Noll–Vo (FNV)](https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function)
14//! non-cryptographic hash function.
15//!
16//! This crate provides the 64-bit versions of FNV-0, FNV-1, and FNV-1a.
17//! FNV hashes are designed to be fast while maintaining a low collision rate,
18//! making them ideal for use in lookup tables and hash maps.
19//!
20//! # 🦀 FNV64-RS
21//!
22//! A lightweight, zero-dependency, `no_std` implementation of the 64-bit **Fowler–Noll–Vo (FNV)** non-cryptographic hash
23//! function in Rust.
24//!
25//! This crate provides high-performance implementations of the **FNV-0**, **FNV-1**, and **FNV-1a** algorithms using const
26//! generics to ensure zero-cost abstractions.
27//!
28//! ## 💡 Why FNV?
29//!
30//! FNV is a non-cryptographic hash function created by Glenn Fowler, Landon Curt Noll, and Kiem-Phong Vo. It is designed to
31//! be:
32//!
33//! 1. Extremely fast to compute.
34//! 2. Easy to implement (only multiplication and XOR).
35//! 3. Low collision rate for common data types.
36//!
37//! It is particularly effective for small data sets like property names in compilers, object keys in scripts, or small
38//! strings.
39//!
40//! ## 🚀 Features
41//!
42//! - **Zero Dependencies**: Pure Rust implementation with no external requirements.
43//! - **`no_std` Support**: Ideal for embedded systems and low-level kernel development.
44//! - **Const Generics**: Uses modern Rust features to provide a generic interface for FNV variants.
45//! - **Standard Library Integration**: Fully implements `core::hash::Hasher` and `core::hash::BuildHasher`.
46//!
47//! ## 📦 Usage
48//!
49//! Add this to your `Cargo.toml`:
50//!
51//! ```toml
52//! [dependencies]
53//! fnv64-rs = "0.1.0"
54//! ```
55//!
56//! ## 🛠️ Using with HashMap
57//!
58//! The FNV algorithm is frequently used in hash maps because of its speed and low collision rate for short keys (like
59//! strings or integers).
60//!
61//! ```rust
62//! use std::collections::HashMap;
63//! use fnv64_rs::FnvBuildHasher;
64//!
65//! // Initialize a HashSet using the FNV-1a BuildHasher
66//! let mut map: HashMap<String, i32, FnvBuildHasher> = HashMap::default();
67//!
68//! map.insert("apple".to_string(), 1);
69//! map.insert("orange".to_string(), 2);
70//!
71//! assert_eq!(map.get("apple"), Some(&1));
72//! assert_eq!(map.get("orange"), Some(&2));
73//! assert_eq!(map.get("pineapple"), None);
74//! ```
75//!
76//! ## 🛠️ Using with HashSet
77//!
78//! The FNV algorithm is frequently used in hash sets because of its speed and low collision rate for short keys (like
79//! strings or integers).
80//!
81//! ```rust
82//! use std::collections::HashSet;
83//! use fnv64_rs::FnvBuildHasher;
84//!
85//! // Initialize a HashMap using the FNV-1a BuildHasher
86//! let mut set: HashSet<String, FnvBuildHasher> = HashSet::default();
87//!
88//! set.insert("apple".to_string());
89//! set.insert("orange".to_string());
90//!
91//! assert!(set.contains("apple"));
92//! assert!(set.contains("orange"));
93//! assert!(!set.contains("pineapple"));
94//! ```
95//!
96//! ## 🛠️ Direct Hashing
97//!
98//! You can use the hasher directly to compute values for specific data:
99//!
100//! ```rust
101//! use core::hash::Hasher;
102//! use fnv64_rs::Fnv1aHasher;
103//!
104//! let mut hasher = Fnv1aHasher::default();
105//! hasher.write(b"hello world");
106//! let result = hasher.finish();
107//!
108//! println!("Hash: {:x}", result);
109//! ```
110//!
111//! ## 📦 Collections (Standard Library)
112//!
113//! [![Feature: std](https://img.shields.io/badge/feature-std-yellow.svg)](https://doc.rust-lang.org/std/)
114//!
115//! When the std feature is enabled, fnv64-rs provides convenient type aliases for standard library collections. These are
116//! pre-configured with FNV hashers and re-exported at the crate root for a seamless developer experience.
117//!
118//! ### Available Aliases
119//!
120//! | Type                 | Hash Algorithm       | Collection |
121//! |:---------------------|:---------------------|:-----------|
122//! | [`FnvHashMap<K, V>`]   | **FNV-1a** (Default) | [`HashMap`][std::collections::HashMap]  |
123//! | [`FnvHashSet<V>`]      | **FNV-1a** (Default) | [`HashSet`][std::collections::HashSet]  |
124//! | [`Fnv1aHashMap<K, V>`] | **FNV-1a**           | [`HashMap`][std::collections::HashMap]  |
125//! | [`Fnv1aHashSet<V>`]    | **FNV-1a**           | [`HashSet`][std::collections::HashSet]  |
126//! | [`Fnv1HashMap<K, V>`]  | **FNV-1**            | [`HashMap`][std::collections::HashMap]  |
127//! | [`Fnv1HashSet<V>`]     | **FNV-1**            | [`HashSet`][std::collections::HashSet]  |
128//! | [`Fnv0HashMap<K, V>`]  | **FNV-0**            | [`HashMap`][std::collections::HashMap]  |
129//! | [`Fnv0HashSet<V>`]     | **FNV-0**            | [`HashSet`][std::collections::HashSet]  |
130//!
131//! > [!TIP]
132//! > On **Nightly Rust**, these aliases also support the **Allocator API**, allowing you to use FNV collections with custom
133//! > memory allocators. Use `--features nightly` to enable this.
134//!
135//! ### 🛠️ Example: Drop-in Replacement
136//!
137//! You can use these aliases directly without needing to manually import or configure a BuildHasher:
138//!
139//! ```rust
140//! # #[cfg(feature = "std")]
141//! # {
142//! use fnv64_rs::{FnvHashMap, FnvHashSet};
143//!
144//! // No complex generic boilerplate needed!
145//! let mut map = FnvHashMap::default();
146//! map.insert("id_01", 100);
147//!
148//! let mut set = FnvHashSet::default();
149//! set.insert("admin");
150//! # }
151//! ```
152//!
153//! ## 📊 Algorithm Variants
154//!
155//! | Variant     | Implementation          | Logic                   | Characteristics                                    |
156//! |:------------|:------------------------|:------------------------|:---------------------------------------------------|
157//! | **FNV-1a**  | `fnv64_rs::Fnv1aHasher` | `(hash ^ byte) * PRIME` | **Recommended.** Best avalanche characteristics.   |
158//! | **FNV-1**   | `fnv64_rs::Fnv1Hasher`  | `(hash * PRIME) ^ byte` | The original FNV-1 specification.                  |
159//! | **FNV-0**   | `fnv64_rs::Fnv0Hasher`  | `hash = 0; ...`         | Deprecated. Included for historical purposes.      |
160//! | **DEFAULT** | `fnv64_rs::FnvHasher`   | `(hash ^ byte) * PRIME` | **Default** implementation. Implements **FNV-1a**. |
161//!
162//! ## ⚖️ License
163//!
164//! This project is licensed under
165//! the [Apache-2.0 License](https://github.com/dante19031999/fnv-rs/tree/main?tab=Apache-2.0-1-ov-file#readme).
166
167pub mod collections;
168mod constants;
169pub mod fnv1;
170pub mod fnv1a;
171
172#[cfg(feature = "std")]
173pub use collections::*;
174pub use constants::*;
175pub use fnv1::*;
176pub use fnv1a::*;
177
178#[cfg(feature = "std")]
179#[doc(inline)]
180pub use collections::FnvHashMap;
181#[cfg(feature = "std")]
182#[doc(inline)]
183pub use collections::FnvHashSet;
184
185/// An alias for the default 64-bit FNV hasher.
186///
187/// This currently points to [`Fnv1aHasher`], which is the recommended
188/// variant for most applications due to its superior bit-dispersion properties.
189#[doc(inline)]
190#[cfg(feature = "std")]
191#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
192pub use fnv1a::Fnv1aHasher as FnvHasher;
193
194/// An alias for the default 64-bit FNV build hasher.
195///
196/// This provides a convenient way to use FNV with standard library collections:
197///
198/// ```rust
199/// use std::collections::HashMap;
200/// use fnv64_rs::FnvBuildHasher;
201///
202/// let mut map: HashMap<String, i32, FnvBuildHasher> = HashMap::default();
203/// map.insert("apple".to_string(), 1);
204/// ```
205#[doc(inline)]
206#[cfg(feature = "std")]
207#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
208pub use fnv1a::Fnv1aBuildHasher as FnvBuildHasher;