Skip to content

Instantly share code, notes, and snippets.

@rkjnsn
Created January 17, 2015 01:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rkjnsn/031cc0979de445167d1b to your computer and use it in GitHub Desktop.
Save rkjnsn/031cc0979de445167d1b to your computer and use it in GitHub Desktop.
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