num crate has been deprecated and generic traits are the most frequently used parts, I developed a small crate
num-traits to fill this gap. It is an implementation of the
num-reform RFC, which only provides six primitive traits (
One) to cover most use cases for generic mathematics.
One are separated because they have been included in the
A big difference from the
num crate is the implementation of an interface for casting numbers. The
num crate introduces
NumCast traits, whereas we only use a
CastInto trait as an equivelence to
Into<Option<T>>. It will be unnecessary if these traits can be included in
The crate is experimental and it is not on
crates.io. Any comments are welcome!
Regarding the casting traits, there's also my
conv crate. It looks like
CastInto is a combination of
ValueInto, without any error types to tell you why a conversion failed, or recover the original input (so it's less than ideal for non-
Oh, another advantage:
ValueInto can statically tell when a conversion cannot possibly fail, allowing you to use a code path that cannot possibly panic, which might make for better code generation.
Thanks for the link. I will check that.
CastInto is only a simple wrapper for
as associated with checking overflow of the type. If the number is beyond the range, it returns a
None. For casting primitive numbers, this is enough, since overflow is the only reason to cause an error; for the extension to other types, returning a
Result is indeed a better choice.
Even with integer types,
Result is useful as it allows you to distinguish between the source being too large or too small to fit into the destination range. This in turn allows for things like
an_i16.value_as::<i8>().unwrap_or_saturate(), which will clamp the result appropriately: you can't do that if all you have is
Also, you return
Option in cases where it's impossible for the conversion to fail, like
u8. This leads to people adding
.unwrap(), which is fine until they refactor something and suddenly the conversion can fail, but they've now masked that. That's why
NoError and a trait defining
.unwrap_ok() so that you can statically assert that a conversion cannot fail without needing a different trait.
Option also doesn't allow you to distinguish between range violation and... whatever the hell you'd call trying to convert NaN into an integer.
Thanks for your comments. I will consider changing it to a
Result. It can provide more error information and more extensibility.