Trait for trait is not implemented

#1

Hello! I have an issue with the following code:

use std::error::Error;

pub trait Backend: Send + Sync {}

pub struct BackendBuilder {
    pub buf: Vec<u8>,
}

pub trait BackendBuilderFor<'a, T: Backend + 'a>: Sized {
    fn build(self) -> Result<T, Box<Error>>;
}

pub trait BoxedBackendBuilderFor<'a, T: Backend + 'a>: BackendBuilderFor<'a, T> {
    fn build_boxed(self) -> Result<Box<Backend + 'a>, Box<Error>> {
        Ok(Box::new(self.build()?))
    }
}

mod backend_a {
    pub struct A {}
    impl super::Backend for A {}
    impl<'a> super::BackendBuilderFor<'a, A> for super::BackendBuilder {
        fn build(self) -> Result<A, Box<super::Error>> {
            Ok(A {})
        }
    }
}

mod backend_b {
    pub struct B {}
    impl super::Backend for B {}
    impl<'a> super::BackendBuilderFor<'a, B> for super::BackendBuilder {
        fn build(self) -> Result<B, Box<super::Error>> {
            Ok(B {})
        }
    }
}

fn main() -> Result<(), Box<Error>> {
    let builder = BackendBuilder { buf: vec![1, 2, 3] };

    let _backend: Box<Backend> = BoxedBackendBuilderFor::<backend_a::A>::build_boxed(builder)?;

    Ok(())
}

(Playground)

I have a trait (BackendBuilderFor), implementors of which can be consumed to construct a generic object (that in turn implements other trait - Backend). Very similar to a one-time-use factory.
My goal is to add a way to build a boxed Backend (dyn trait) for all the implementors of the BackendBuilderFor. I’ve tried doing that by adding a BoxedBackendBuilderFor - the code seems to be alright, but the compiler rejects it.

Please help! I need to achieve the goal I described - not nesessarily by adding the BoxedBackendBuilderFor trait - if there are other ways I’d take them. One thing that I can’t do is manually implement boxed builders at each backend mod, because I already have generic builders implemented (i.e. manually implementing build_boxed for backend_a::A is not a viable solution).

0 Likes

#2

BoxedBackendBuilderFor is a trait that is not implemented on anything, so it will get mad at you for trying to use it with anything. What you want to do is blanket implement it for any type that satisfies the requirements by adding this line:

impl <
    'a,
    T: Backend + 'a, 
    O: BackendBuilderFor<'a, T>
> BoxedBackendBuilderFor<'a, T> for O {} 

So as to implement it for any valid O.

0 Likes

#4

Thanks, it solved the issue!

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

0 Likes