-
-
Save yiqing-95/9d2585dc8425c9e984c6d23326b2c17d to your computer and use it in GitHub Desktop.
Shared via Rust Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Red; | |
struct Green; | |
// Any trait allows dynamic type checks | |
use std::any::{Any, TypeId}; | |
use std::collections::HashMap; | |
// Every Feature also implements Any trait | |
trait Feature : Any { | |
} | |
impl Feature for Red {} | |
impl Feature for Green {} | |
type FeatureHash = HashMap<TypeId, Box<Any>>; | |
trait FeatureFinder { | |
fn add<T: Feature>(&mut self, feature: T); | |
fn find<T: Feature>(&self) -> Option<&T>; | |
} | |
impl FeatureFinder for FeatureHash { | |
fn add<T: Feature>(&mut self, feature: T) { | |
self.insert(TypeId::of::<T>(), Box::new(feature)); | |
} | |
fn find<T: Feature>(&self) -> Option<&T> { | |
self.get(&TypeId::of::<T>()).and_then(|f| f.downcast_ref()) | |
} | |
} | |
fn main() { | |
let mut features = FeatureHash::new(); | |
features.add(Red); | |
features.add(Green); | |
// Note that find() magically works! It picks the type from the variable. | |
let red: &Red = features.find().expect("red should be in there"); | |
let green: &Green = features.find().expect("green should be in there, too"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment