ababo
ababo

Reputation: 1632

How to specialise trait implementations for different type parameters?

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?

Upvotes: 1

Views: 56

Answers (1)

Michael Zajac
Michael Zajac

Reputation: 55569

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
  }
}

Upvotes: 2

Related Questions