chiark / gitweb /
W
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 5 Jun 2023 16:08:41 +0000 (17:08 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 5 Jun 2023 16:08:41 +0000 (17:08 +0100)
src/main.rs

index b860f634dde970a54df5cc3fef153943f38af6be..13d9400b50426fd2e87491775b4938f48da81a4a 100644 (file)
@@ -2,9 +2,12 @@
 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>>;
@@ -27,14 +30,15 @@ trait EatsFood {
 
 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 {
@@ -43,7 +47,8 @@ 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>>() {
@@ -59,10 +64,14 @@ fn main() {
    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()*/)
 }