ids_service 2.1.3

Library that allows to generate unique Ids.
Documentation
// SPDX-License-Identifier: MIT
// Copyright (c) ids_service contributors

//! Library that allows generating unique ids. It keeps a cache filled using background threads.
//!
//! If the cache is empty (the number of requests is too high) an id is calculated on the fly.
//! This will slow down obtaining the id but there is no error when the cache is empty.
//!
//! To generate unique ids the library uses an array of bytes from a random number generator
//! combined with a nanosecond timestamp since UNIX_EPOCH, then hashes both together.
//!
//! The library is composed of two modules with similar API but different hash algorithms:
//!
//! ## `crypto_hash`
//! Uses one of the SHA-3 algorithms from the [`sha3`](https://crates.io/crates/sha3) crate.
//!
//! ## `rust_hash`
//! Uses [`std::collections::hash_map::DefaultHasher`] from the Rust standard library.
//!
//! According to your requirements, you may choose which module you need. The negative impact of
//! using `crypto_hash` is performance and resource usage — throughput is roughly half compared to
//! `rust_hash`.
//!
//! Indicative throughput on an Intel i7:
//! * `crypto_hash` (SHA-512): above 2'000'000 ids/sec
//! * `rust_hash`: above 5'000'000 ids/sec
//!
//! The id can be encoded as:
//! * Hexadecimal lower case string
//! * Base64 string
//! * Base64-URL string
//! * Base32 string
//! * JSON string
//!
//! # Quick Start
//!
//! ## `crypto_hash`
//! ```
//! #[cfg(feature = "crypto")]
//! {
//! use ids_service::crypto_hash::*;
//! use ids_service::common::*;
//!
//! let mut ids = IdsService::default();
//! ids.start();
//! let _ = ids.filled_at_percent_event(10).recv();
//! println!("Get an id: {}", ids.get_id().as_hex());
//! println!("Get another id: {}", ids.get_id().as_base64());
//! println!("Current cache size: {}", ids.get_cache_len());
//! ids.stop();
//! }
//! ```
//!
//! Create an id without the caching service:
//! ```
//! #[cfg(feature = "crypto")]
//! {
//! use ids_service::crypto_hash::*;
//!
//! println!("SHA-512 id: {}", create_id_as_sha512());
//! println!("SHA-256 id: {}", create_id_as_sha256());
//! }
//! ```
//!
//! ## `rust_hash`
//! ```
//! #[cfg(feature = "rust")]
//! {
//! use ids_service::rust_hash::*;
//! use ids_service::common::*;
//!
//! let mut ids = IdsService::default();
//! ids.start();
//! let _ = ids.filled_event().recv();
//! println!("Get an id: {}", ids.get_id().as_hex());
//! println!("Get an id as base64: {}", ids.get_id().as_base64());
//! println!("Get an id as json: {}", ids.get_id().as_json());
//! ids.stop();
//! }
//! ```
//!
//! Create an id without the caching service:
//! ```
//! #[cfg(feature = "rust")]
//! {
//! use ids_service::rust_hash::*;
//!
//! println!("id: {}", create_id());
//! }
//! ```

/// Crypto hash module - available with `crypto` or `all` features (default).
#[cfg(feature = "crypto")]
pub mod crypto_hash;

/// Rust hash module — **deprecated**, use the `crypto` feature and `crypto_hash` module instead.
#[deprecated(
    since = "2.1.0",
    note = "Use the 'crypto' feature and `crypto_hash` module instead"
)]
#[cfg(feature = "rust")]
pub mod rust_hash;

/// Module with shared types used by both `crypto_hash` and `rust_hash`.
pub mod common {
    use std::sync::LazyLock;

    /// Default number of fill threads equals the number of available logical CPUs.
    pub static NUMBER_OF_FILL_THREAD: LazyLock<usize> = LazyLock::new(|| {
        std::thread::available_parallelism()
            .map(|n| n.get())
            .unwrap_or(4)
    });

    /// Trait defining the possible encoding output formats for an id.
    pub trait Encode: Sized {
        /// Encode as lowercase hexadecimal string.
        fn as_hex(&self) -> String;

        /// Encode as Base64 string.
        fn as_base64(&self) -> String;

        /// Encode as Base64-URL string.
        fn as_base64_url(&self) -> String;

        /// Encode as Base32 string.
        fn as_base32(&self) -> String;

        /// Encode as a JSON string containing multiple representations.
        fn as_json(&self) -> String;
    }

    /// Trait for retrieving ids from an [`IdsService`](crate::crypto_hash::IdsService).
    pub trait Uids {
        /// The id type returned by this service.
        type Id;

        /// Get an id. Never fails — falls back to on-the-fly generation if cache is empty.
        fn get_id(&mut self) -> Self::Id;

        /// Get an id directly from the cache. Returns `None` if the cache is empty.
        fn get_id_from_cache(&mut self) -> Option<Self::Id>;
    }

    /// Trait for lifecycle management of an ids service.
    pub trait Service {
        /// Start the background threads that keep the cache filled.
        fn start(&mut self);

        /// Gracefully stop background threads and clear the cache.
        fn stop(&mut self);

        /// Restart the service (stop then start).
        fn restart(&mut self) {
            self.stop();
            self.start();
        }
    }
}