3 releases (stable)
Uses old Rust 2015
1.0.1 | Oct 12, 2019 |
---|---|
1.0.0 | Sep 27, 2019 |
0.1.0 | Sep 1, 2017 |
#2451 in Rust patterns
7KB
whiteout
whiteout
provides macros that erase the type of any value into an impl Trait
for a given trait. This gives you a value that can only be use with the methods of that trait, and whose type is unnameable.
#[macro_use] extern crate whiteout;
fn main() {
let a = erase!(10, std:ops::Add<i64, Output=i64>);
assert_eq!(a + 10, 20);
}
Since we sometimes want to use these values together, whiteout
provides both a one-time macro and a macro that produces a function which returns a consistent unnameable type, allowing multiple erased values to be used in conjunction. See the documentation for more info.
lib.rs
:
whiteout
provides macros that erase the type of any value into
an impl Trait
for a given trait.
Examples
Single values can be erased using the erase!
macro.
let a = erase!(10, std::ops::Add<i64, Output=i64>);
let b = erase!(5, std::ops::Add<i64, Output=i64>);
assert_eq!(a + 10, 20);
assert_eq!(b + 10, 15);
// This fails, the types are opaque
// assert_eq!(a + b, 15);
These erased values can't be used together, though; they have different
anonymized types. Therefore, you sometimes need the eraser!
macro.
#[macro_use]
extern crate whiteout;
// Define a custom trait into which types will be erased.
trait MyTrait:
std::ops::Add<Self, Output=Self> // Allow the operation we need
+ std::convert::From<i32> // Allow converting from concrete values
+ std::fmt::Debug // Allow printing (for use with assert!())
+ PartialEq // Allow comparison (for use with assert_eq!())
{}
// Implement MyTrait for all possible types.
impl<T> MyTrait for T
where T: std::ops::Add<Self, Output=Self>
+ std::convert::From<i32>
+ std::fmt::Debug
+ PartialEq
{}
// Create an eraser function for the custom trait
eraser!(erase_my_trait, MyTrait);
fn main() {
// Use the eraser function.
// If we used erase!(10, MyTrait); for these
// they would be of different types.
let a = erase_my_trait(10);
let b = erase_my_trait(5);
assert_eq!(a + b, 15.into());
}