pub trait IntegerId:
Copy
+ Eq
+ Debug
+ Send
+ Sync
+ 'static {
type Int: UnsignedPrimInt;
const MIN_ID: Option<Self>;
const MAX_ID: Option<Self>;
const MIN_ID_INT: Option<Self::Int>;
const MAX_ID_INT: Option<Self::Int>;
const TRUSTED_RANGE: Option<TrustedRangeToken<Self>> = None;
// Required methods
fn from_int_checked(id: Self::Int) -> Option<Self>;
fn to_int(self) -> Self::Int;
// Provided methods
fn from_int(id: Self::Int) -> Self { ... }
unsafe fn from_int_unchecked(id: Self::Int) -> Self { ... }
}Expand description
An identifier which can be sensibly converted to/from an unsigned integer value.
The type should not carry any information beyond that of the integer index,
and be able to losslessly convert back and forth from Self::Int.
It is possible that not all values of the underlying integer type are valid,
allowing core::num::NonZero and C-like enums to implement this trait.
This is intended mostly for newtype wrappers around integer indexes, and the primitive integer types themselves.
The value of the underlying integer must be consistent. It cannot change over the course of the program’s lifetime.
§Safety
With one exception, this trait is safe to implement and cannot be relied upon by memory safety.
If the implementation of IntegerId::from_int_unchecked makes any sort of unsafe assumptions
about the validity of the input, then the rest of the trait must be implemented correctly.
This means that implementations of this trait fall into two categories:
- Potentially incorrect implemented entirely using safe code, where
from_int_unchecked(x)is equivalent to callingfrom_int_checked(x).unwrap(); - Traits where
from_int_uncheckedcould trigger undefined behavior on an invalid value, but every other part of this trait can be trusted to be implemented correctly.
In both these cases, the following code is always safe:
fn foo<T: IntegerId>(x: T) -> T {
let y = x.to_int();
let z = unsafe { T::from_int_unchecked(y) };
z
}In case 1, it doesn’t matter if x.to_int() produces garbage data,
because T::from_int_unchecked method is safe to call.
In case 2, the to_int method can be trusted to produce a valid value y that cannot fail
when passed to T::from_int_unchecked.
The requirement for correctness in this case also apply to all sub-traits in this crate,
including IntegerIdContiguous and IntegerIdCounter.
So an unsafe implementation of from_int_unchecked can be similarly trusted to accept
all integer values between IntegerId::MIN_ID and IntegerId::MAX_ID.
This restriction allows avoiding unnecessary checks when ids are stored to/from another data structure.
Despite this requirement, I still consider this trait safe to implement,
because safety can only be violated by an unsafe implementation offrom_int_unchecked.
This type should not have interior mutability.
This is guaranteed by the Copy bound.
Required Associated Constants§
Sourceconst MIN_ID: Option<Self>
const MIN_ID: Option<Self>
The value of this type with the smallest integer value,
or None if this type is uninhabited.
Sourceconst MAX_ID: Option<Self>
const MAX_ID: Option<Self>
The value of this type with the largest integer value,
or None if this type is uninhabited.
Sourceconst MIN_ID_INT: Option<Self::Int>
const MIN_ID_INT: Option<Self::Int>
The value of Self::MIN_ID a primitive integer,
or None if this type is uninhabited.
This is necessary because trait methods cannot be marked const.
Sourceconst MAX_ID_INT: Option<Self::Int>
const MAX_ID_INT: Option<Self::Int>
The value of Self::MAX_ID a primitive integer,
or None if this type is uninhabited.
This is necessary because trait methods cannot be marked const.
Provided Associated Constants§
Sourceconst TRUSTED_RANGE: Option<TrustedRangeToken<Self>> = None
const TRUSTED_RANGE: Option<TrustedRangeToken<Self>> = None
Indicates that the type’s implementation of IntegerId::to_int can be trusted
to only return values in the range MIN_ID_INT..=MAX_ID_INT.
Creating this token means that all of these guarantees can be relied upon for memory safety. This allows unsafe code to avoid bounds checks, but turns a correctness invariant into a soundness invariant.
§Safety
The result of Self::to_int must always fall in the range MIN_ID_INT..=MAX_ID_INT.
If EnumId is implemented,
then the requirements of the EnumId trait must be met as well.
In particular, the index must always fit in a u32
and have the appropriately Array and BitSet items.
Required Associated Types§
Sourcetype Int: UnsignedPrimInt
type Int: UnsignedPrimInt
The underlying integer type.
Every valid instance of Self should correspond to a valid Self::Int.
However, the other direction may not always be true.
Required Methods§
Sourcefn from_int_checked(id: Self::Int) -> Option<Self>
fn from_int_checked(id: Self::Int) -> Option<Self>
Create an id from the underlying integer value,
returning None if the value is invalid.
Provided Methods§
Sourcefn from_int(id: Self::Int) -> Self
fn from_int(id: Self::Int) -> Self
Create an id from the underlying integer value, panicking if the value is invalid.
§Correctness
A value returned by this method should never trigger
an error if passed to Self::from_int_checked.
This means the validity of certain ids can’t change over the course of the program.
Sourceunsafe fn from_int_unchecked(id: Self::Int) -> Self
unsafe fn from_int_unchecked(id: Self::Int) -> Self
Create an id from the underlying integer value, triggering undefined behavior if the value is invalid.
§Safety
If the corresponding Self::from_int_checked method would fail,
this triggers undefined behavior.
The default implementation just invokes Self::from_int.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".