Skip to content

Instantly share code, notes, and snippets.

@yiqing-95
Forked from anonymous/playground.rs
Created October 5, 2022 10:18
Show Gist options
  • Save yiqing-95/9d2585dc8425c9e984c6d23326b2c17d to your computer and use it in GitHub Desktop.
Save yiqing-95/9d2585dc8425c9e984c6d23326b2c17d to your computer and use it in GitHub Desktop.
Shared via Rust Playground
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