Created
November 14, 2022 03:50
-
-
Save Zomatree/3a8fff30a2228a4bb7104e8290a385ea to your computer and use it in GitHub Desktop.
This file contains hidden or 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
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