pub trait GuaranteesFiniteValues: ValidationPolicyReal { }
Expand description
A marker trait for validation policies that guarantee finite real values.
This trait serves as a compile-time marker to identify policies that ensure
all validated real values are always finite (never NaN or infinite). It enables
the implementation of full equality (Eq
) and hashing (Hash
) for
validated types, allowing them to be used as keys in hash-based collections
like HashMap
and HashSet
.
§Enabled Features
When a validation policy implements this trait, the corresponding validated types
(like RealValidated<K>
) automatically gain:
- Full Equality (
Eq
): Equality becomes reflexive, symmetric, and transitive since NaN values (which violate these properties) are excluded. - Hashing (
Hash
): Combined withEq
, this allows validated types to be used as keys in hash-based collections likeHashMap
andHashSet
.
§Hashing Implementation Details
The Hash
implementation for validated types:
- Delegates to the underlying raw type’s
RawRealTrait::compute_hash
method - Handles IEEE 754 floating-point edge cases correctly (e.g., signed zeros)
- Maintains the contract that
a == b
implieshash(a) == hash(b)
- Works with both native
f64
and arbitrary-precisionrug
types
§Design Decision: No Total Ordering
This trait intentionally does not enable total ordering (Ord
) because:
- The library’s comparison functions use efficient reference-based
PartialOrd
Max
/Min
traits provide better performance than value-basedOrd
- Mathematical operations work naturally with partial ordering semantics
§Use Cases
This marker trait enables validated numerical types to be used in contexts that
require Eq
and Hash
:
use num_valid::{RealNative64StrictFinite, functions::Max};
use std::collections::{HashMap, HashSet};
use try_create::TryNew;
// Use as HashMap keys (requires Eq + Hash)
let mut scores = HashMap::new();
let player1 = RealNative64StrictFinite::try_new(1.5).unwrap();
scores.insert(player1, 100);
// Use in HashSet (requires Eq + Hash)
let mut unique_values = HashSet::new();
unique_values.insert(RealNative64StrictFinite::try_new(3.14).unwrap());
// Comparison still works efficiently with PartialOrd
let a = RealNative64StrictFinite::try_new(1.0).unwrap();
let b = RealNative64StrictFinite::try_new(2.0).unwrap();
assert!(a < b); // Uses PartialOrd
assert_eq!(a.max(&b), &b); // Uses library's Max trait
§Hash Collision Considerations
The hashing implementation ensures:
- Consistent hashes for mathematically equal values
- Proper handling of floating-point edge cases
- Compatibility with both native and arbitrary-precision backends
- No hash collisions due to NaN values (which are excluded by design)
§Currently Implemented By
StrictFinitePolicy<T, P>
: The primary policy that rejects NaN, infinity, and subnormal values.DebugValidationPolicy<StrictFinitePolicy<T, P>>
: A wrapper that applies strict validation only in debug builds.
§Safety and Correctness
This trait should only be implemented by validation policies that genuinely guarantee finite values. Incorrect implementation could lead to hash collisions or violated equality contracts in the methods that rely on this guarantee.
The trait is designed as a marker trait (no methods) to emphasize that it’s purely a compile-time contract rather than runtime functionality.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.