How to specialise trait implementations for different type parameters?

Viewed 34

I need to call some logic that is specific to type parameter. How can I achieve that?

I try the following code:

trait Conn {}

struct SqliteConn;
struct PostgreConn;

impl Conn for SqliteConn {}
impl Conn for PostgreConn {}

trait Data {
    fn init(&mut self);
}

struct Db<C: Conn> {
    conn: C,
}

impl<C: Conn> Db<C> {
    fn new(conn: C) -> Self {
        let mut db = Self { conn };
        db.init(); // fails here
        db
    }
}

impl Data for Db<SqliteConn> {
    fn init(&mut self) {
        // sqlite3-specific init
    }
}

impl Data for Db<PostgreConn> {
    fn init(&mut self) {
        // postgre-specific init
    }
}

Rust compiler complains with "no method named init found for struct Db in the current scope" error. How can I fix this?

1 Answers

You need to require that Db<C> has an implementation of Data, which you can do with where:

impl <C: Conn> Db<C> where Db<C>: Data {
  fn new(conn: C) -> Self {
    let mut db = Self { conn };
    db.init();
    db
  }
}
Related