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>
.