0

I am having trouble understanding why I am running into error E0277. I have the following code:

#[derive(Queryable, Identifiable, Serialize, Deserialize)]
pub struct User {
    pub id: i32,
    pub email: String,
    pub password: String,
    pub first_name: String,
    pub last_name: String,
}


struct UserForEmail {
    email: String,
}

impl Message for UserForEmail {
    type Result = Result<Option<User>, Error>;
}

impl Handler<UserForEmail> for DbExecutor {
    type Result = Result<Option<User>, Error>;

    fn handle(&mut self, msg: UserForEmail, _ctx: &mut Self::Context) -> Self::Result {
        let conn = self.connection_pool.get()?;

        let user_res = users.filter(email.eq(&msg.email)).load(&conn)?;

        match user_res.len() {
            0 => Ok(None),
            1 => Ok(user_res[0]),
            _ => Err(format_err!("Found more than one user for email")), // TODO make this an actual error
        }
    }
}

and when I try to compile I get the following error:

error[E0277]: the trait bound `std::option::Option<domain::user::User>: diesel::Queryable<(diesel::sql_types::Integer, diesel::sql_types::Text, diesel::sql_types::Text, diesel::sql_types::Text, diesel::sql_types::Text), diesel::pg::Pg>` is not satisfied
  --> src/domain/user.rs:60:59
   |
60 |         let user_res = users.filter(email.eq(&msg.email)).load(&conn)?;
   |                                                           ^^^^ the trait `diesel::Queryable<(diesel::sql_types::Integer, diesel::sql_types::Text, diesel::sql_types::Text, diesel::sql_types::Text, diesel::sql_types::Text), diesel::pg::Pg>` is not implemented for `std::option::Option<domain::user::User>`
   |
   = help: the following implementations were found:
             <std::option::Option<T> as diesel::Queryable<diesel::sql_types::Nullable<ST>, DB>>
   = note: required because of the requirements on the impl of `diesel::query_dsl::LoadQuery<diesel::r2d2::PooledConnection<diesel::r2d2::ConnectionManager<diesel::PgConnection>>, std::option::Option<domain::user::User>>` for `diesel::query_builder::SelectStatement<schema::users::table, diesel::query_builder::select_clause::DefaultSelectClause, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::WhereClause<diesel::expression::operators::Eq<schema::users::columns::email, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>>>`

I don't understand why diesel::Queryable needs to be implemented for Option<User> in this case. If I switch the Result type of the message to be Result<User, Error> then the problem goes away

rykeeboy
  • 645
  • 2
  • 8
  • 22
  • 4
    `T:Trait` does not give you `Option:Trait` automatically. – vikram2784 Mar 04 '19 at 06:14
  • 1
    This was just a dumb mistake on my part. I forgot to wrap the returned value in Some in the case where len == 1, so user_res was having its type coerced to Vec – rykeeboy Mar 04 '19 at 13:22

0 Answers0