universal_radix_sort 1.0.0

A high-performance, generic Radix Sort implementation for Rust supporting integers, floats, and strings
Documentation
//! Enumeration types for configuring Radix Sort behavior.
//!
//! This module defines the core configuration options for the Radix Sort algorithm,
//! including data type strategies, sort directions, and byte processing orders.

/// Defines the data type strategy for the Radix Sort.
///
/// Each variant corresponds to a specific transformation logic required to correctly
/// sort different types of data using radix-based techniques.
///
/// # Type Mapping
///
/// | Variant | Compatible Types | Transformation |
/// |---------|-----------------|----------------|
/// | `SignedInteger` | `i8`, `i16`, `i32`, `i64`, `i128`, `isize` | Sign-bit flipping |
/// | `UnsignedInteger` | `u8`, `u16`, `u32`, `u64`, `u128`, `usize` | Direct byte extraction |
/// | `Float` | `f32`, `f64` | IEEE 754 bit transformation |
/// | `String` | `String`, `&str` | UTF-8 byte extraction |
///
/// # Examples
///
/// ```rust
/// use universal_radix_sort::RadixDataType;
///
/// // For signed integers
/// let int_type = RadixDataType::SignedInteger;
///
/// // For floating-point numbers
/// let float_type = RadixDataType::Float;
///
/// // For strings
/// let string_type = RadixDataType::String;
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RadixDataType {
    /// For unsigned integers and raw byte sequences.
    /// Uses purely unsigned comparison logic without transformation.
    UnsignedInteger,

    /// For standard signed integer types.
    /// Applies a sign-bit transformation to handle negative numbers correctly.
    SignedInteger,

    /// For floating-point numbers (f32, f64).
    /// Applies IEEE 754 bit transformation to handle decimals, NaN, and infinity.
    Float,

    /// For string types with lexicographical ordering.
    /// Uses UTF-8 byte extraction with MSD-first strategy.
    String,
}

/// Defines the sort order direction.
///
/// # Examples
///
/// ```rust
/// use universal_radix_sort::SortDirection;
///
/// // Ascending: 1, 2, 3, 4, 5
/// let asc = SortDirection::Ascending;
///
/// // Descending: 5, 4, 3, 2, 1
/// let desc = SortDirection::Descending;
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SortDirection {
    /// Sort from smallest to largest (e.g., 1, 2, 3).
    Ascending,

    /// Sort from largest to smallest (e.g., 3, 2, 1).
    Descending,
}

impl SortDirection {
    /// Returns `true` if the direction is ascending.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use universal_radix_sort::SortDirection;
    ///
    /// assert!(SortDirection::Ascending.is_ascending());
    /// assert!(!SortDirection::Descending.is_ascending());
    /// ```
    #[inline]
    pub fn is_ascending(self) -> bool {
        matches!(self, SortDirection::Ascending)
    }

    /// Returns `true` if the direction is descending.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use universal_radix_sort::SortDirection;
    ///
    /// assert!(SortDirection::Descending.is_descending());
    /// assert!(!SortDirection::Ascending.is_descending());
    /// ```
    #[inline]
    pub fn is_descending(self) -> bool {
        matches!(self, SortDirection::Descending)
    }

    /// Reverses the sort direction.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use universal_radix_sort::SortDirection;
    ///
    /// assert_eq!(SortDirection::Ascending.reverse(), SortDirection::Descending);
    /// assert_eq!(SortDirection::Descending.reverse(), SortDirection::Ascending);
    /// ```
    #[inline]
    pub fn reverse(self) -> Self {
        match self {
            SortDirection::Ascending => SortDirection::Descending,
            SortDirection::Descending => SortDirection::Ascending,
        }
    }
}

/// Defines the order in which bytes/digits are processed during sorting.
///
/// # Performance Characteristics
///
/// | Order | Best For | Stability | Memory |
/// |-------|----------|-----------|--------|
/// | `LsbFirst` | Fixed-width integers, floats | Stable | O(n) |
/// | `MsbFirst` | Variable-width strings, early termination | Stable | O(n + k) |
///
/// # Examples
///
/// ```rust
/// use universal_radix_sort::ProcessingOrder;
///
/// // LSB-first: Process from least significant byte (rightmost)
/// let lsb = ProcessingOrder::LsbFirst;
///
/// // MSB-first: Process from most significant byte (leftmost)
/// let msb = ProcessingOrder::MsbFirst;
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ProcessingOrder {
    /// Least Significant Byte/Digit first.
    ///
    /// Standard for numeric Radix Sort. Efficient and cache-friendly for fixed-width data.
    /// Processes bytes from right to left (byte 0, 1, 2, ...).
    LsbFirst,

    /// Most Significant Byte/Digit first.
    ///
    /// Essential for lexicographical sorting of strings. Allows early termination
    /// when differences are found in higher-order bytes. Processes bytes from left to right.
    MsbFirst,
}

impl Default for ProcessingOrder {
    /// Returns the default processing order based on typical use cases.
    ///
    /// For numeric types, `LsbFirst` is generally more efficient.
    /// For strings, `MsbFirst` provides better lexicographical ordering.
    fn default() -> Self {
        ProcessingOrder::LsbFirst
    }
}