Crates.io | multitype |
lib.rs | multitype |
version | 0.14.0 |
created_at | 2025-08-13 09:41:15.163946+00 |
updated_at | 2025-09-20 09:02:14.710581+00 |
description | Fundamental type traits. |
homepage | |
repository | https://mandelbrot.dk/bjoernager/multitype/ |
max_upload_size | |
id | 1793474 |
size | 172,323 |
MultiType is Rust a crate for generalising fundamental types via traits.
MultiType provideds traits such as Uint
and Float
traits to abstract over a set of equivalent primitive types.
These traits are intended to provide one-to-one copies of the interfaces that the primitive types define.
The complete list of traits is:
Int
IntLeast16
IntLeast32
IntLeast64
Uint
UintLeast16
UintLeast32
UintLeast64
Float
FloatLeast32
FloatLeast64
StdFloat
Array
Any given type may implement at most one of the aforementioned trait groups; thus, for example, any type that implemets Float
can be assumed to possibly implement FloatLeast32
but never Uint
.
For the sake of compatibility with {f16, f32, f64, f128}::to_int_unchecked
, we also defined our own FloatToInt
trait.
Note that all traits provided by this crate are sealed and cannot be implemented by third-party crates (at least currently).
MultiType defines different traits for generalising arithmetic types:
Int
for i8
, i16
, i32
, i64
, i128
, and isize
;Uint
for u8
, u16
, u32
, u64
, u128
, and usize
;Float
for f16
, f32
, f64
, and f128
.Furthermore, StdFloat
extends the Float
trait with functionality that is typically only available in std
's floating-point types.
The basic, arithmetic traits guarantee a minimum size that is equivalent to the smallest member of its group, e.g. Uint
is at least u8
and Float
is at least f16
.
Additionally, these three arithmetic traits have subtraits that guarantee wider types, for example:
i16
and wider implement IntLeast16
;i32
and wider implement IntLeast32
;Extremely-wide traits, e.g. IntLeast8
or IntLeast128
, are considered redundant and are thus not provided.
MultiType also provides the Array
trait for generalising array types – most often over their length.
An example of this trait's usecase is actually in this crate:
Take, for instance, the definition of Uint
: It has a Bytes
associated type that is used by the bytewise constructors and destructors:
pub unsafe trait Uint: /* .. */ {
type Bytes;
fn from_ne_bytes(bytes: Self::Bytes) -> Self;
fn to_ne_bytes(self) -> Self::Bytes;
// ..
}
Now, anyone that would want to use the output of to_ne_bytes
:to_ne_bytes) wouldn't really have that many choices with regard to what to do with it.
So, MultiType defines the Array
trait:
use multitype::Array;
pub unsafe trait Uint: /* .. */ {
type Bytes: Array<Scalar = u8>;
// ..
}
With it, it's possible for users to generically use Uint::to_ne_bytes
as an array type through the trait methods.
A generic Fibonacci sequence:
use multitype::Uint;
fn f<T: Uint>(x: T) -> T {
let mut y = T::from(0x0u8);
let mut y_m1 = T::from(0x0u8);
let mut y_m2 = T::from(0x1u8);
let mut i = T::from(0x0u8);
while i < x {
y = y_m1 + y_m2;
y_m2 = y_m1;
y_m1 = y;
i += T::from(0x1u8);
}
y
}
assert_eq!(f(0u8), 0);
assert_eq!(f(1u8), 1);
assert_eq!(f(2u16), 1);
assert_eq!(f(3u16), 2);
assert_eq!(f(4u32), 3);
assert_eq!(f(5u32), 5);
assert_eq!(f(6u64), 8);
assert_eq!(f(7u64), 13);
Generic array indexing:
use core::f32;
use multitype::{Array, Float};
fn complicated_neg<T: Float>(value: T) -> T {
let mut bytes = value.to_le_bytes();
// Invert the sign bit -- which is always the most
// significant bit of the most significant byte.
*bytes.as_mut_slice().last_mut().unwrap() ^= 0b10000000;
T::from_le_bytes(bytes)
}
assert_eq!(complicated_neg( 1.0f64), -1.0f64);
assert_eq!(complicated_neg(-1.0f64), 1.0f64);
assert_eq!(complicated_neg(f32::NEG_INFINITY), f32::INFINITY);
Default features:
alloc
std
Dependency features:
alloc
: Enables compatibility with alloc
facilitiesstd
: Enables compatibility with std
facilitiesUnstable features:
clone_to_uninit
: Enables CloneToUninit
requirementsconst_param_ty
: Enables ConstParamTy_
requirementsf16
: Enables support for f16
f128
: Enables support for f128
freeze
: Enables Freeze
requirementsstep
: Enables Step
requirementsstructural_partial_eq
: Enables StructuralPartialEq
requirementstrusted_step
: Enables TrustedStep
requirementsunstable-docs
: Enables unstable documentation featuresuse_cloned
: Enables UseCloned
requirementsUnstable features can be expected to be removed as their facilities stabilise.
The goal of MultiType is to provide generic traits that bind as much of the standard interfaces as possible. We will attempt to backport all trivial interfaces as much as possible, but if any given interface is deemed to complicated, we will bump the MSRV to leverage it from the standard implementation.
When const
-compatible traits land, MultiType will implement the feature as quickly as possible.
Copyright © 2025 Gabriel Bjørnager Jensen.
MultiType is distributed under either an MIT licence (see LICENCE-MIT
) or version 2.0 of the Apache License (see LICENCE-APACHE
), at your option.