use rocket::fairing::AdHoc; use rocket::response::{Debug, status::Created}; use rocket::serde::{Serialize, Deserialize, json::Json}; use rocket_db_pools::{Database, Connection}; use rocket_db_pools::diesel::{MysqlPool, prelude::*}; type Result> = std::result::Result; #[derive(Database)] #[database("diesel_mysql")] struct Db(MysqlPool); #[derive(Debug, Clone, Deserialize, Serialize, Queryable, Insertable)] #[serde(crate = "rocket::serde")] #[diesel(table_name = posts)] struct Post { #[serde(skip_deserializing)] id: Option, title: String, text: String, #[serde(skip_deserializing)] published: bool, } diesel::table! { posts (id) { id -> Nullable, title -> Text, text -> Text, published -> Bool, } } #[post("/", data = "")] async fn create(mut db: Connection, mut post: Json) -> Result>> { diesel::sql_function!(fn last_insert_id() -> BigInt); let post = db.transaction(|mut conn| Box::pin(async move { diesel::insert_into(posts::table) .values(&*post) .execute(&mut conn) .await?; post.id = Some(posts::table .select(last_insert_id()) .first(&mut conn) .await?); Ok::<_, diesel::result::Error>(post) })).await?; Ok(Created::new("/").body(post)) } #[get("/")] async fn list(mut db: Connection) -> Result>>> { let ids = posts::table .select(posts::id) .load(&mut db) .await?; Ok(Json(ids)) } #[get("/")] async fn read(mut db: Connection, id: i64) -> Option> { posts::table .filter(posts::id.eq(id)) .first(&mut db) .await .map(Json) .ok() } #[delete("/")] async fn delete(mut db: Connection, id: i64) -> Result> { let affected = diesel::delete(posts::table) .filter(posts::id.eq(id)) .execute(&mut db) .await?; Ok((affected == 1).then(|| ())) } #[delete("/")] async fn destroy(mut db: Connection) -> Result<()> { diesel::delete(posts::table).execute(&mut db).await?; Ok(()) } pub fn stage() -> AdHoc { AdHoc::on_ignite("Diesel MySQL Stage", |rocket| async { rocket.attach(Db::init()) .mount("/diesel-async", routes![list, read, create, delete, destroy]) }) }