-
-
Save rust-play/ac646af496c7984e90c003f5f12c2d55 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
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, TypeId}; | |
use std::fmt::Debug; | |
pub trait Resource: Any + Debug { | |
fn combine_fn(&self) -> fn(left: Box<dyn Resource>, right: Box<dyn Resource>) -> Box<dyn Resource>; | |
} | |
#[derive(Debug)] | |
struct File(u32); | |
impl File { | |
fn combine(left: File, right: File) -> File { | |
File(left.0 + right.0) | |
} | |
} | |
// taken from Box::downcast as I cannot cast Box<dyn Resource> to Box<dyn Any> | |
// https://github.com/rust-lang/rfcs/issues/2765#issuecomment-703950666 | |
pub fn downcast<T: Resource>(res: Box<dyn Resource>) -> Result<Box<T>, Box<dyn Resource>> { | |
if <dyn Resource>::type_id(&*res) == TypeId::of::<T>() { | |
unsafe { | |
let raw: *mut (dyn Resource) = Box::into_raw(res); | |
Ok(Box::from_raw(raw as *mut T)) | |
} | |
} else { | |
Err(res) | |
} | |
} | |
impl Resource for File { | |
fn combine_fn(&self) -> fn(left: Box<dyn Resource>, right: Box<dyn Resource>) -> Box<dyn Resource> { | |
fn dyn_combine(left: Box<dyn Resource>, right: Box<dyn Resource>) -> Box<dyn Resource> { | |
let left: File = *downcast::<File>(left).unwrap(); | |
let right: File = *downcast::<File>(right).unwrap(); | |
Box::new(File::combine(left, right)) | |
} | |
dyn_combine | |
} | |
} | |
fn main() { | |
let a = File(1); | |
let b = File(10); | |
let a: Box<dyn Resource> = Box::new(a); | |
let b: Box<dyn Resource> = Box::new(b); | |
let c = a.combine_fn()(a,b); | |
dbg![c]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment