首先,需要给 diesel 添加 c2d2 feature:

diesel = { version = "2.1.0", features = ["mysql", "r2d2"] }

然后创建 AppState 结构体:

use diesel::{MysqlConnection, r2d2::{Pool, ConnectionManager}};
#[derive(Clone)]
pub struct AppState {
    pub pool: Pool<ConnectionManager<MysqlConnection>> // 数据库连接池
}

创建 build_pool function:

pub fn build_pool(database_url: &str) -> Pool<ConnectionManager<MysqlConnection>> {
    let manager = ConnectionManager::<MysqlConnection>::new(database_url);
    let pool = r2d2::Pool::builder()
        .build(manager)
        .expect("Failed to create pool.");
    pool
}

创建 actix-web 的 App 时,通过 app_data 注入 AppState:

let pool = build_pool("mysql://root:cpchain@127.0.0.1:3306/cpchain");
let state = AppState {
    pkg_dir: opts.pkg_dir.clone(),
    pool
};

// ...

App::new()
    .app_data(web::Data::new(state.clone()))
    //...

Handler 的参数中,注入 AppState 即可使用 Pool:

#[post("/publish")]
async fn create(data: web::Data<AppState>, package: web::Json<PackageInfo>) -> impl Responder {
// ...
let conn = &mut data.pool.get().expect("Failed to get connection");
diesel::insert_into(schema::packages::table)
        .values(&new_package)
        .execute(conn)
        .expect("Error saving new post");
// ...
}