rusttraitsdefault-implementation

Call a function if a Rust trait is implemented, do nothing otherwise


I am surprisingly stuck on a Rust problem that looks counterintuitively simple, and yet I cannot seem to figure it out. I am nearly starting to think it might be unsolvable, and yet I'm not sure what are the fundamental reasons, if any, why it should be.

Say I have a trait

trait T {
    fn t(&self);
}

I would like to implement a generic function f<X>(x: &X) such that:

I feel so inexplicably lost. Of course, two implementations of f will not work because of duplicate definitions. I thought about adding an helper trait H with some function h that by default does nothing, then implementing H for every X: T, overloading h to invoke x.t(). But, then every X that does not implement T would not implement H either, so that doesn't help. Right?

Am I missing something? Is implementing f possible, but very convoluted? Or is there any fundamental reason why implementing f should be impossible altogether?

(If possible, I'd like to avoid dynamic dispatch, as this is quite an intensely used part of my code. But, at this point, I'll go with whatever's possible!)


Solution

  • You can use downcast and downcast_mut from Any to test if the contained value is of a given type:

    use std::any::Any;
    
    trait T {
        fn t(&self);
        fn as_any(&self) -> &dyn Any;
    }
    
    struct TCode;
    
    impl T for TCode {
        fn t(&self) {
            println!("hello");
        }
        fn as_any(&self) -> &dyn Any {
            self
        }
    }
    
    fn main() {
        let x = TCode {};
        if let Some(TCode {}) = x.as_any().downcast_ref::<TCode>() {
            x.t()
        }
    }
    

    Playground