Search code examples
rusttraits

How to triple pendent traits un Rust without using dyn?


I have three traits that are dependent on each other, but I can't find a way to define these traits statically without using dyn.

Defining two seems very simple:

pub trait TA<B: TB<Self>> {
    fn getB() -> Option<B>;
}

pub trait TB<A: TA<Self>> {
    fn getA() -> Option<A>;

}

But defining similar thing with three traits seems impossible (the code bellow doesn't compile):

pub trait TA<B: TB, C: TC> {
    fn getB() -> Option<B>;
    fn getC() -> Option<C>;
}

pub trait TB<A: TA, C: TC> {
    fn getA() -> Option<A>;
    fn getC() -> Option<C>;
}

pub trait TC<A: TA, B: TB> {
    fn getA() -> Option<A>;
    fn getB() -> Option<B>;
}

Solution

  • It seems like with another thought it was easier than I thought.

    pub trait TA<B: TB<Self, C>, C: TC<Self, B>> {
        fn getB() -> Option<B>;
        fn getC() -> Option<C>;
    }
    
    pub trait TB<A: TA<Self, C>, C: TC<Self, A>> {
        fn getA() -> Option<A>;
        fn getC() -> Option<C>;
    }
    
    pub trait TC<A: TA<A, Self>, B: TB<B, Self>> {
        fn getA() -> Option<A>;
        fn getB() -> Option<B>;
    }
    

    Edit: @trenctl solution bellow looks much cleaner

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=062b05bf63efb1b6bfb2575bf963ff62

    trait Ta {
        type B: Tb<A = Self, C = Self::C>;
        type C: Tc<A = Self, B = Self::B>;
        fn get_b(&self) -> Option<Self::B>;
        fn get_c(&self) -> Option<Self::C>;
    }
    
    trait Tb {
        type A: Ta<B = Self, C = Self::C>;
        type C: Tc<B = Self, A = Self::A>;
        fn get_a(&self) -> Option<Self::A>;
        fn get_c(&self) -> Option<Self::C>;
    }
    
    trait Tc {
        type A: Ta<C = Self, B = Self::B>;
        type B: Tb<C = Self, A = Self::A>;
        fn get_a(&self) -> Option<Self::A>;
        fn get_b(&self) -> Option<Self::B>;
    }