Add trait for converting numeric types to i64
@@ -21,6 +21,7 @@ pub mod win_perm;
use std::error;
use std::fmt;
use std::marker::PhantomData;
+use std::mem;
use std::result;
use std::str::FromStr;
@@ -70,3 +71,63 @@ where
{
s.serialize_str(&t.to_string())
}
+
+/// Provide a way to convert numeric types safely to i64
+trait ToI64 {
+ fn to_i64(self) -> i64;
+}
+
+impl ToI64 for usize {
+ fn to_i64(self) -> i64 {
+ if mem::size_of::<usize>() >= mem::size_of::<i64>() && self > i64::max_value() as usize {
+ error!(
+ "Tried to convert an out-of-range usize ({}) to i64; using i64::max_value()",
+ self
+ );
+ i64::max_value()
+ } else {
+ self as i64
+ }
+ }
+}
+
+impl ToI64 for u64 {
+ fn to_i64(self) -> i64 {
+ if mem::size_of::<u64>() >= mem::size_of::<i64>() && self > i64::max_value() as u64 {
+ error!(
+ "Tried to convert an out-of-range u64 ({}) to i64; using i64::max_value()",
+ self
+ );
+ i64::max_value()
+ } else {
+ self as i64
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn conversion_of_usize_to_i64() {
+ let too_big = usize::max_value();
+ let just_right: usize = 42;
+ let zero: usize = 0;
+
+ assert_eq!(too_big.to_i64(), i64::max_value());
+ assert_eq!(just_right.to_i64(), 42);
+ assert_eq!(zero.to_i64(), 0);
+ }
+
+ #[test]
+ fn conversion_of_u64_to_i64() {
+ let too_big = u64::max_value();
+ let just_right: u64 = 42;
+ let zero: u64 = 0;
+
+ assert_eq!(too_big.to_i64(), i64::max_value());
+ assert_eq!(just_right.to_i64(), 42);
+ assert_eq!(zero.to_i64(), 0);
+ }
+}
