Sample implementation of a Widen trait for Rust
| use widen::Widen; | |
| use widen::widen as w; // Use w as shorthand for widening | |
| // Contains Widen trait, impls, and widen() convenience function | |
| mod widen { | |
| // Performs a lossless conversion of an integer to a wider type | |
| pub trait Widen<T> { | |
| fn widen(self) -> T; | |
| } | |
| // All built in integers "widen" to themselves. This may not be desired if | |
| // we want use of the trait to guarantee that widening is happening. It also | |
| // may be desirable to enumerate these explicitly, since nothing prevents | |
| // other types from implementing Int. | |
| impl<T: ::std::num::Int> Widen<T> for T { | |
| fn widen(self) -> T { | |
| self | |
| } | |
| } | |
| // Widen signed integers | |
| impl Widen<i16> for i8 { | |
| fn widen(self) -> i16 { | |
| self as i16 | |
| } | |
| } | |
| impl Widen<i32> for i8 { | |
| fn widen(self) -> i32 { | |
| self as i32 | |
| } | |
| } | |
| impl Widen<i64> for i8 { | |
| fn widen(self) -> i64 { | |
| self as i64 | |
| } | |
| } | |
| impl Widen<i32> for i16 { | |
| fn widen(self) -> i32 { | |
| self as i32 | |
| } | |
| } | |
| impl Widen<i64> for i16 { | |
| fn widen(self) -> i64 { | |
| self as i64 | |
| } | |
| } | |
| impl Widen<i64> for i32 { | |
| fn widen(self) -> i64 { | |
| self as i64 | |
| } | |
| } | |
| // Widen unsigned integers | |
| impl Widen<u16> for u8 { | |
| fn widen(self) -> u16 { | |
| self as u16 | |
| } | |
| } | |
| impl Widen<u32> for u8 { | |
| fn widen(self) -> u32 { | |
| self as u32 | |
| } | |
| } | |
| impl Widen<u64> for u8 { | |
| fn widen(self) -> u64 { | |
| self as u64 | |
| } | |
| } | |
| impl Widen<u32> for u16 { | |
| fn widen(self) -> u32 { | |
| self as u32 | |
| } | |
| } | |
| impl Widen<u64> for u16 { | |
| fn widen(self) -> u64 { | |
| self as u64 | |
| } | |
| } | |
| impl Widen<u64> for u32 { | |
| fn widen(self) -> u64 { | |
| self as u64 | |
| } | |
| } | |
| // Widen unsigned integers to larger signed integers | |
| impl Widen<i16> for u8 { | |
| fn widen(self) -> i16 { | |
| self as i16 | |
| } | |
| } | |
| impl Widen<i32> for u8 { | |
| fn widen(self) -> i32 { | |
| self as i32 | |
| } | |
| } | |
| impl Widen<i64> for u8 { | |
| fn widen(self) -> i64 { | |
| self as i64 | |
| } | |
| } | |
| impl Widen<i32> for u16 { | |
| fn widen(self) -> i32 { | |
| self as i32 | |
| } | |
| } | |
| impl Widen<i64> for u16 { | |
| fn widen(self) -> i64 { | |
| self as i64 | |
| } | |
| } | |
| impl Widen<i64> for u32 { | |
| fn widen(self) -> i64 { | |
| self as i64 | |
| } | |
| } | |
| // Convenience function | |
| pub fn widen<F, T>(val: F) -> T | |
| where F:Widen<T> | |
| { | |
| val.widen() | |
| } | |
| } | |
| fn main() { | |
| fn func1(_: i16) {} | |
| fn func2(_: i32) {} | |
| fn func3(_: i64) {} | |
| let a = 1i16; | |
| let b = 2u32; | |
| // Use trait directly | |
| func1(3i16.widen()); | |
| func2(a.widen()); | |
| func3(b.widen()); | |
| // Use convenience function | |
| func1(w(a)); | |
| func2(w(4i8)); | |
| func3(w(b)); | |
| // Errors | |
| //func1(w(5i32)); | |
| //func2(w(b)); | |
| //func3(w(6u64)); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment