tensor-programming / rust_api_part_2

7 stars 2 forks source link

Any chance to update this? #1

Open josefrichter opened 2 years ago

josefrichter commented 2 years ago

Hi, I can't seem to find way to properly update this and make it run. After all, it's a tutorial for beginners.

Seems like there are major changes in Rocket (v0.5 now) and r2d2, I think the biggest trouble is somewhere in the pooling in db.rs file, but I just can't figure out and getting plenty of errors on build no matter what I try.

Is there any chance to have this updated, please? It seems to me that someone with more experience would probably see the problem right away. Thank you!

ghost commented 2 years ago

I managed to correct the old pre 0.5 syntax with this snippet (assuming you are stuck in the first function):

Remember that for strange destiny reason, Rocket is now "async". So you'll have to use attribute decorators and async functions.

Here is db.rs using the modern stack:

use diesel::r2d2::ConnectionManager;
use diesel::sqlite::SqliteConnection;
use rocket::http::Status;
use rocket::outcome::try_outcome;
use rocket::outcome::Outcome;
use rocket::request::{self, FromRequest};
use rocket::{Request, State};
use std::ops::Deref;

// Create a wrapper for the r2d2 Pool object
pub type Pool = diesel::r2d2::Pool<ConnectionManager<SqliteConnection>>;

pub fn init_pool(db_url: String) -> Pool {
    let manager = ConnectionManager::<SqliteConnection>::new(db_url);
    diesel::r2d2::Pool::new(manager).expect("Failed to init database pool!")
}

// Create a guard for our database connection
pub struct Conn(pub diesel::r2d2::PooledConnection<ConnectionManager<SqliteConnection>>);

#[rocket::async_trait]
impl<'r> FromRequest<'r> for Conn {
    type Error = ();

    async fn from_request(request: &'r Request<'_>) -> request::Outcome<Conn, ()> {
        let pool = try_outcome!(request.guard::<&State<Pool>>().await);
        match pool.get() {
            Ok(conn) => Outcome::Success(Conn(conn)),
            Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())),
        }
    }
}

impl Deref for Conn {
    type Target = SqliteConnection;

    // Rust already inlines this, no need to specify the previous decorator.
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

NOTE that I'm using SQLiteConnection so you'll have to change this to your liking.