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

index 59582c80f87d323ebb21ab4e6afc5390de8c6ddc..b860f634dde970a54df5cc3fef153943f38af6be 100644 (file)
@@ -2,20 +2,20 @@
 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;
@@ -32,22 +32,24 @@ impl EatsFood for Frog {
       "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
     }
@@ -55,7 +57,7 @@ impl CastToAnyTrait for Arc<Frog> {
 
 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();