Skip to content

Instantly share code, notes, and snippets.

Created April 11, 2016 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/53b022b1f0dd87c232f5df98dc6cc342 to your computer and use it in GitHub Desktop.
Save anonymous/53b022b1f0dd87c232f5df98dc6cc342 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
#![feature(specialization)]
use std::marker::PhantomData;
#[derive(Clone, Copy)]
struct Key<K, V> {
_k: PhantomData<K>,
_v: PhantomData<V>,
}
trait KeyType<N> {
fn is_value() -> bool {
false
}
}
trait SameType<A, B> {}
impl <T> SameType<T, T> for T {}
impl Key<(), ()> {
pub fn new() -> Key<(), ()> {
Key {
_k: PhantomData,
_v: PhantomData,
}
}
}
impl <T, A, B> KeyType<T> for Key<A, B> where A: KeyType<T> {
default fn is_value() -> bool {
A::is_value()
}
}
impl <T, A, B> KeyType<T> for Key<A, B> where A: KeyType<T>, T: SameType<T, B> {
fn is_value() -> bool {
true
}
}
impl <T> KeyType<T> for () {
fn is_value() -> bool {
false
}
}
impl <K, V> Key<K, V> {
pub fn with<N>(self) -> Key<Key<K, V>, N> {
Key {
_k: PhantomData,
_v: PhantomData,
}
}
pub fn has<N>(self) -> bool where K: KeyType<N> {
<Self as KeyType<N>>::is_value()
}
}
fn main() {
let key = Key::new()
.with::<i32>()
.with::<u8>();
println!("{}", key.has::<bool>());
println!("{}", key.has::<i32>());
println!("{}", key.has::<i8>());
println!("{}", key.has::<u8>());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment