use std::any::{Any,TypeId};
use std::sync::Arc;
-pub trait HasPseudoMethods: Any + Send + Sync + 'static {
+use downcast_rs::{DowncastSync, impl_downcast};
+
+pub trait HasPseudoMethods: DowncastSync {
fn cast_to_instance(&self, arc: Arc<dyn HasPseudoMethods>, tp: TypeId) -> Option<Box<dyn Any>>;
}
+impl_downcast!(sync HasPseudoMethods);
/*
pub trait HasPseudoMethodsExt {
fn cast_to<T: 'static>(&self) -> Option<Box<T>>;
struct Frog;
+impl HasFeet for Frog {
+ fn how_many_feet(&self) -> usize { 4 }
+}
+
+/*
impl EatsFood for Frog {
fn favorite_food(&self) -> &'static str {
"flies"
}
-}
-/*
-impl HasFeet for Frog {
- fn how_many_feet(&self) -> usize { 4 }
}*/
impl HasPseudoMethods for Frog {
// table. I'm not sure if that's needed.
fn cast_to_instance(&self, arc: Arc<dyn HasPseudoMethods>, tp: TypeId) -> Option<Box<dyn Any>> {
if tp == TypeId::of::<Arc<dyn HasFeet>>() {
- let arc: Arc<Frog> = Arc::downcast::<Frog>(arc);
+ let arc: Arc<dyn Any + Send + Sync> = DowncastSync::into_any_arc(arc);
+ let arc: Arc<Frog> = Arc::downcast::<Frog>(arc).unwrap();
let arc: Arc<dyn HasFeet> = arc.clone();
return Some(Box::new(arc));
/* } else if tp == TypeId::of::<Arc<dyn EatsFood>>() {
let frog = Arc::new(Frog);
let erased_frog: Arc<dyn HasPseudoMethods> = frog as _;
- let with_feet: Arc<dyn HasFeet> = *erased_frog.cast_to::<Arc<dyn HasFeet>>().unwrap();
- let eats_food: Arc<dyn EatsFood> = *erased_frog.cast_to::<Arc<dyn EatsFood>>().unwrap();
+ let with_feet: Box<dyn Any> = erased_frog.cast_to_instance(
+ erased_frog.clone(),
+ TypeId::of::<Arc<dyn HasFeet>>(),
+ ).unwrap();
+
+ let with_feet: Box<Arc<dyn HasFeet>> = with_feet.downcast().unwrap();
- println!("A frog has {} feet and eats {}.",
- with_feet.how_many_feet(),
- eats_food.favorite_food())
+ println!("A frog has {} feet and eats .",
+ with_feet.how_many_feet(),/*
+ eats_food.favorite_food()*/)
}