1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
//! Serial (or auto-increment) integers make great unique identifers. They do //! not need to be large (i.e. using more memory) to prevent collisions and they //! are always unique until they reach their max value, mimicking the behavior //! of PostgreSQL's `SERIAL` data type. Creating serial values has minimal //! performance impact because it relies on simple adding rather than hashing or //! randomizing. //! //! This crate provides a generator (that is also an iterator) that outputs //! serial values. By default, any unsigned integer from the standard library //! can be generated. This is essentially a counter, a simple iterator for //! integers. This crate is appropriately tiny. //! //! For safety and stability, the generator "saturates" the values instead of //! overflowing. This guarantess that the output values are unique to that //! generator (except for the greatest possible value, e.g. u8::MAX or //! u32::MAX). //! //! # Panics //! //! None //! //! # Examples //! //! A simple example. //! //! ```rust //! # use serial_int::SerialGenerator; //! let mut gen = SerialGenerator::<u32>::new(); //! //! assert_eq!(0, gen.generate()); //! assert_eq!(1, gen.generate()); //! ``` //! //! A complex example showing the use of `static` and concurrency //! //! ```rust //! # use serial_int::SerialGenerator; //! # use lazy_static::lazy_static; //! # use std::{sync::{Arc, Mutex}, thread}; //! # //! fn main() { //! let users_mutex = Arc::new(Mutex::new(Vec::new())); //! let users_clone = Arc::clone(&users_mutex); //! //! let handle = thread::spawn(move || { //! let alice = User::new("alice@domain.xyz"); //! let mary = User::new("mary@domain.xyz"); //! let mut users = users_clone.lock().unwrap(); //! //! users.push(alice); //! users.push(mary); //! }); //! //! handle.join().unwrap(); //! //! let bob = User::new("bob@domain.xyz"); //! let fred = User::new("fred@domain.xyz"); //! let mut users = users_mutex.lock().unwrap(); //! //! users.push(bob); //! users.push(fred); //! //! assert_eq!(0, users[0].id); //! assert_eq!(1, users[1].id); //! assert_eq!(2, users[2].id); //! assert_eq!(3, users[3].id); //! } //! //! lazy_static! { //! static ref USER_ID_GEN: Mutex<SerialGenerator> //! = Mutex::new(SerialGenerator::new()); //! } //! //! struct User { //! id: u32, //! email: String, //! } //! //! impl User { //! pub fn new(email: &str) -> Self { //! User { //! id: USER_ID_GEN.lock().unwrap().generate(), //! email: email.to_string(), //! } //! } //! } //! ``` #![warn(missing_docs)] mod serial; mod serial_generator; mod tests; pub use serial::Serial; pub use serial_generator::SerialGenerator;