Get generic trait from ordinal one without Self type?

Viewed 628

I have two traits, one ordinal (Foo), another generic (TypedFoo<T>). I have several structures, each of them have both traits implemented.

Is it possible to convert from Foo to TypedFoo<T>, without converting to an intermediate structure?

trait Foo {
    fn f(&mut self);
}

trait TypedFoo<T> {
    fn get(&self) -> T;
}

#[derive(Clone)]
struct Data(i32);

impl Foo for Data {
    fn f(&mut self) {
        self.0 += 1;
    }
}

impl TypedFoo<Data> for Data {
    fn get(&self) -> Data {
        self.clone()
    }
}

//struct Data2(f64);
//impl Foo for Data2...
//impl TypedFoo<Data2> for Data2..

fn main() {
    let v: Vec<Box<Foo>> = vec![Box::new(Data(1))];    
} 

I can change Foo to this:

trait Foo {
    fn f(&mut self);
    fn get_self(&self) -> &Any;
}

Then get v[0].get_self() downcast_ref to Data, and then Data to &TypedFoo<Data>.

But is it possible to get &TypedFoo<Data> from &Foo without knowing "data type", some analog of Any but for a trait.

I imagine syntax like this:

let foo: &Foo = ...;
if let Some(typed_foo) = foo.cast::<Data>() {

} 

My question is different from Can I cast between two traits? because I have one generic and one ordinal trait. If I had two ordinal traits then the solution would be as simple as:

trait Foo {
    fn f(&mut self);
    fn as_typed_foo(&self) -> &TypedFoo;
}

Since TypedFoo is generic, none of the answers in that question help me. One possible solution could be:

trait Foo {
    fn f(&mut self);
    fn cast(&mut self, type_id: ::std::any::TypeId) -> Option<*mut ::std::os::raw::c_void>;
}

I am not sure how safe it is to cast *mut TypedFoo<T> -> *mut ::std::os::raw::c_void and then back to *mut TypedFoo<T>.

1 Answers
Related