use std::any::{Any,TypeId};
use std::sync::Arc;
-pub trait CastToAnyTrait {
- fn cast_to_instance(&self, tp: TypeId) -> Option<Box<dyn Any>>;
+pub trait HasPseudoMethods: Any + Send + Sync + 'static {
+ fn cast_to_instance(&self, arc: Arc<dyn HasPseudoMethods>, tp: TypeId) -> Option<Box<dyn Any>>;
}
-
-pub trait CastToAnyTraitExt {
+/*
+pub trait HasPseudoMethodsExt {
fn cast_to<T: 'static>(&self) -> Option<Box<T>>;
}
-impl<T:CastToAnyTrait+?Sized> CastToAnyTraitExt for T {
+impl<T:HasPseudoMethods+?Sized> HasPseudoMethodsExt for T {
fn cast_to<U: 'static>(&self) -> Option<Box<U>> {
let instance = self.cast_to_instance(TypeId::of::<U>())?;
instance.downcast().ok()
}
-}
+}*/
trait HasFeet {
fn how_many_feet(&self) -> usize;
"flies"
}
}
-
+/*
impl HasFeet for Frog {
fn how_many_feet(&self) -> usize { 4 }
-}
+}*/
-impl CastToAnyTrait for Arc<Frog> {
+impl HasPseudoMethods for Frog {
// Note: if you wanted to be able to add more traits to Frog elsewhere, you would
// need a registry of cast-to-trait objects, similar to the existing dispatch
// table. I'm not sure if that's needed.
- fn cast_to_instance(&self, tp: TypeId) -> Option<Box<dyn Any>> {
+ 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<dyn HasFeet> = self.clone();
+ let arc: Arc<Frog> = Arc::downcast::<Frog>(arc);
+ let arc: Arc<dyn HasFeet> = arc.clone();
return Some(Box::new(arc));
- } else if tp == TypeId::of::<Arc<dyn EatsFood>>() {
+/* } else if tp == TypeId::of::<Arc<dyn EatsFood>>() {
let arc: Arc<dyn EatsFood> = self.clone();
return Some(Box::new(arc));
+*/
}
None
}
fn main() {
let frog = Arc::new(Frog);
- let erased_frog: &dyn CastToAnyTrait = &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();