How to create a struct that implements a generic trait?

I'm trying to implement a generic repository. I want to create a generic repo to manage every struct that implements the Persistence trait. So I have:

pub trait Persistence {}

#[derive(Debug)]
pub struct Foo {
    id: String,
    name: String
}

impl Persistence for Foo {}

pub trait Repository<T> where T: Persistence {
    fn new() -> Result<Self, String> where Self: Sized;
}

pub struct MyRepository {}

impl<T> Repository<T> for MyRepository
    where T: Persistence {

    fn new() -> Result<Self, String> where Self: Sized {
        Ok(MyRepository {})
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn should_create_the_expected_repo() {
        let repo = MyRepository::new().unwrap(); // HERE IS THE ERROR
        // some assertions
    }
}

This code does not compile due to the error Type annotations needed
I tried to specify the bound, but I can't get the right syntax, I'm trying something like

let repo : MyRepository<Foo> = MyRepository::new().unwrap();

Or even

let repo = MyRepository::<Foo>::new().unwrap();

This last one prints an error that says, obviously, that MyRepository doesn't expect any generic argument.
Does anyone have any advice, please?

The correct syntax for this case is:

let repo = <MyRepository as Repository<Foo>>::new().unwrap();

Or:

let repo: MyRepository = Repository::<Foo>::new().unwrap();

This will tell the compiler which Repository implementation to use.

2 Likes