generic_constants

Crates.iogeneric_constants
lib.rsgeneric_constants
version0.1.0
created_at2025-11-09 17:07:31.831498+00
updated_at2025-11-09 17:07:31.831498+00
descriptionTraits providing type-generic numeric constants (Zero, One, ..., OneHundredTwentySeven) implemented across common integer and float types.
homepagehttps://github.com/christoffetzer/generic_constants
repositoryhttps://github.com/christoffetzer/generic_constants
max_upload_size
id1924295
size119,553
Scontain (scontain)

documentation

https://docs.rs/generic_constants

README

Typed Constants via Traits: Zero, One, ..., OneHundredTwentySeven

This crate provides a family of traits, one per integer constant in the range 0 through 127. Each trait defines a single associated constant whose value is implemented across common numeric types (i8, u8, i16, u16, i32, i64, usize, f32, f64, etc.).

The traits allow writing generic code that refers to numeric constants without requiring conversion or From bounds, and without depending on unstable generic constant features.

Motivation

When writing generic numeric code in Rust, one often wants to refer to numeric constants that work across different numeric types. However:

T::from(127) requires trait bounds and may not be available for all numeric types

as conversions are lossy when crossing from signed to unsigned or integer to float

Generic constant expressions are still limited in stable Rust

This crate provides a simple and predictable alternative: one trait per number, one associated constant, implemented for common numeric types.

Example

use generic_constants::OneHundredTwentySeven;

fn saturate_to_127<T: OneHundredTwentySeven + Ord>(value: T) -> T {
    if value > T::ONE_HUNDRED_TWENTY_SEVEN {
        T::ONE_HUNDRED_TWENTY_SEVEN
    } else {
        value
    }
}

fn main() {
    assert_eq!(saturate_to_127(200u32), 127u32);
    assert_eq!(saturate_to_127(50u32), 50u32);
}

No casts, no conversion traits, no intermediate types.

Trait Structure

Each trait follows the same pattern:

pub trait OneHundredTwentySeven {
    const ONE_HUNDRED_TWENTY_SEVEN: Self;
}

and is implemented for a consistent set of numeric types:

All signed and unsigned integers: i8 u8 i16 u16 i32 u32 i64 u64 i128 u128 isize usize

Floating types: f32, f64

Example implementation:

impl OneHundredTwentySeven for i8   { const ONE_HUNDRED_TWENTY_SEVEN: Self = 127; }
impl OneHundredTwentySeven for u8   { const ONE_HUNDRED_TWENTY_SEVEN: Self = 127; }
impl OneHundredTwentySeven for f32  { const ONE_HUNDRED_TWENTY_SEVEN: Self = 127.0; }
// etc...

Naming Conventions

Traits are named using English number words: Zero, One, Two, ..., FortyTwo, ..., OneHundredTwentySeven

Associated constants follow the same English spelling, but in uppercase with underscores

This ensures:

  • Fully deterministic naming

  • No ambiguity regarding spelling, hyphens, short forms, or ordinals

  • Easy auto-completion in IDEs

Use Cases

  • Generic numeric algorithms

  • Compile-time bounds and limits

  • Avoiding lossy casts

  • Writing crates that work across integer and float types without feature gates

  • Type-directed constant selection

Status and Scope

Range: 0 to 127 inclusive

All traits are stable, pure Rust, and require no features

No dependencies

If desired, the range can be extended. Open an issue if you need OneHundredTwentyEight and beyond.

License

This project is available under:

  • MIT License

  • Apache License 2.0

At your choice.

Commit count: 0

cargo fmt