Search code examples
rustactix-websurrealdb

SurrealDB Response take method not working


I am learning Rust and SurrealDB and I am trying to query an user but I am getting a bizzare error.

Here's the code:

#[post("/register")]
async fn register_user_handler(
    body: web::Json<RegisterUserSchema>,
    data: web::Data<AppState>,
) -> impl Responder {
    let result = data
        .db
        .query("SELECT * from users where email = $email LIMIT 1")
        .bind(("email", &body.email))
        .await
        .unwrap();

    println!("From here: {:#?}", result.take(0));  // <------- This is the error line

    let uuid_id = Uuid::new_v4();

    let user = User {
        _id: uuid_id.to_string(),
        name: body.name.to_owned(),
        username: body.username.to_owned(),
        email: body.email.to_owned().to_lowercase(),
        password: "".to_string(),
        provider: "".to_string(),
        age: None,
        phone: "".to_string(),
        photo: "".to_string(),
        location: "".to_string(),
    };

    let new_user: Result<Vec<Option<User>>, Error> = data.db.create("users").content(user).await;

    if new_user.is_err() {
        println!("{:#?}", new_user);
    }

    println!("{:#?}", new_user);

    let json_response = serde_json::json! ({
        "status": "success".to_string(),
    });

    HttpResponse::Ok().json(json_response)
}

I am getting this error which is not making any sense at all because it works fine in the docs and all the examples I have seen. I googled the error but I found nothing. I tried ChatGPT but still the same error.

error[E0277]: the trait bound `i32: QueryResult<_>` is not satisfied
   --> src\app\users\views.rs:37:46
    |
37  |     println!("From here: {:#?}", result.take(0));
    |                                         ---- ^ the trait `QueryResult<_>` is not implemented for `i32`
    |                                         |
    |                                         required by a bound introduced by this call
    |
    = help: the following other types implement trait `QueryResult<Response>`:
              <usize as QueryResult<Vec<T>>>
              <usize as QueryResult<surrealdb::sql::Value>>
              <usize as QueryResult<std::option::Option<T>>>
note: required by a bound in `surrealdb::Response::take`
   --> C:\Users\Ayush\.cargo\registry\src\index.crates.io-6f17d22bba15001f\surrealdb-1.4.2\src\api\method\query.rs:344:40
    |
344 |     pub fn take<R>(&mut self, index: impl opt::QueryResult<R>) -> Result<R>
    |                                           ^^^^^^^^^^^^^^^^^^^ required by this bound in `Response::take`

I googled the error, looked at the docs and some examples and I found no difference in the implementation. I asked ChatGPT and it gave me the same example.


Solution

  • You need to specify the type that you're expecting to get from the response. Your practical choices are Option<T>, Vec<T>, or a dynamic Value. I'm assuming you're expecting something that looks like your existing User struct.

    From the examples in the documentation that would normally look like this:

    let user: Option<User> = result.take(0).unwrap();
    println!("From here: {:#?}", user);
    

    Or if you really want to annotate the type in-line, specify it like so:

    println!("From here: {:#?}", result.take::<Option<User>>(0));