Skip to content

Instantly share code, notes, and snippets.

@Zomatree
Created November 14, 2022 03:50
Show Gist options
  • Save Zomatree/3a8fff30a2228a4bb7104e8290a385ea to your computer and use it in GitHub Desktop.
Save Zomatree/3a8fff30a2228a4bb7104e8290a385ea to your computer and use it in GitHub Desktop.
use std::{any::Any, collections::HashMap};
trait VTable<G = ()> {
const NAME: &'static str;
fn table(&self) -> HashMap<&str, &'static dyn Any>;
fn get<T: 'static>(&self, name: &str) -> &T {
let table = self.table();
let any = table[name];
any.downcast_ref().unwrap()
}
}
struct Foo<T> {
value: T
}
impl VTable<(u8,)> for Foo<u8> {
const NAME: &'static str = "Foo";
fn table(&self) -> HashMap<&str, &'static dyn Any> {
let mut map = HashMap::<&str, &'static dyn Any>::new();
map.insert("incr", &(foo_incr as fn(&mut Self)) as &dyn Any);
map
}
}
impl VTable<(String,)> for Foo<String> {
const NAME: &'static str = "Foo";
fn table(&self) -> HashMap<&str, &'static dyn Any> {
let mut map = HashMap::<&str, &'static dyn Any>::new();
map.insert("push_str", &(foo_push_str as fn(&mut Self, &str)) as &dyn Any);
map
}
}
fn foo_incr(this: &mut Foo<u8>) {
this.value += 1;
}
fn foo_push_str(this: &mut Foo<String>, value: &str) {
this.value.push_str(value)
}
fn main() {
let mut foo = Foo {
value: 1
};
foo.get::<fn(&mut Foo<u8>)>("incr")(&mut foo);
println!("{}", foo.value);
let mut foo2 = Foo {
value: "asdasd".to_string()
};
foo2.get::<fn(&mut Foo<String>, &str)>("push_str")(&mut foo2, "qwe");
println!("{}", foo2.value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment