我是Rust的新手我试图创建一个tokio-postgres连接池到一个处理程序,它应该使用连接填充数据库表。我使用deadpool-postgres,它似乎创建了池。问题是我无法将池传递给处理程序。
下面是与问题相关的代码:
use axum::{
extract::State,
routing::{get, post},
Router,
http::{Response, StatusCode},
extract::Form,
response::{IntoResponse, Redirect}
};
use std::{convert::Infallible, fs, net::SocketAddr};
use tower_http::cors::{Any, CorsLayer};
use tokio_postgres::NoTls;
use deadpool_postgres::{Config, ManagerConfig, Pool, RecyclingMethod};
#[derive(Clone)]
struct AppState {
db_pool: Pool
}
impl AppState {
async fn make_pool() -> Self {
let mut config = Config::new();
config.user = Some("postgres".to_string());
config.password = Some("postgres".to_string());
config.dbname = Some("localhost".to_string());
config.host = Some("localhost".to_string());
config.port = Some(5432);
config.manager = Some(ManagerConfig { recycling_method: RecyclingMethod::Fast });
let pool = config.create_pool(None, NoTls).unwrap();
pool.resize(15);
AppState {
db_pool: pool,
}
}
}
async fn handle_form(Form(data): Form<FormData>, async fn handle_form(Form(data): Form<FormData>, State(client): State<AppState>) -> Result<Redirect, PoolError> {
println!("->>\thandle_form__handler called");
let conn = client.db_pool.get().await.unwrap();
let values = (&data.nome, &data.cognome, &data.email);
let query = "INSERT INTO users (nome, cognome, email) VALUES ($1, $2, $3)";
if let Err(e) = conn.execute(query, &[&values.0, &values.1, &values.2])
.await.map_err(|e| Into::<deadpool_postgres::PoolError>::into(e)) {
eprintln!("error executing query: {}", e);
return Err(e.into());
}
Ok(Redirect::to("/form/success/"))
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let client = AppState::make_pool().await;
let cors = CorsLayer::new().allow_origin(Any);
let app = Router::new()
.route("/", get(index_handler))
.route("/about/", get(about_handler))
.route("/form/", get(form_handler))
.route("/form/submit-form/", post(handle_form))
.route("/form/success/", get(success_handler))
.with_state(client)
.layer(cors);
let addr = SocketAddr::from(([127, 0, 0, 1], 8000));
println!("listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
Ok(())
}
报告的错误为:
error[E0277]: the trait bound `fn(Form<FormData>, State<AppState>) -> impl Future<Output = Result<Redirect, deadpool::managed::errors::PoolError<tokio_postgres::Error>>> {handle_form}: Handler<_, _, _>` is not satisfied
--> src/main.rs:85:43
|
85 | .route("/form/submit-form/", post(handle_form))
| ---- ^^^^^^^^^^^ the trait `Handler<_, _, _>` is not implemented for fn item `fn(Form<FormData>, State<AppState>) -> impl Future<Output = Result<Redirect, deadpool::managed::errors::PoolError<tokio_postgres::Error>>> {handle_form}`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `Handler<T, S, B>`:
<Layered<L, H, T, S, B, B2> as Handler<T, S, B2>>
<MethodRouter<S, B> as Handler<(), S, B>>
note: required by a bound in `post`
--> /home/bontxa/.cargo/registry/src/github.com-1ecc6299db9ec823/axum-0.6.18/src/routing/method_routing.rs:407:1
|
407 | top_level_handler_fn!(post, POST);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `post`
= note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
为了解决这个错误,我修改了这一行:
async fn handle_form(Form(data): Form<FormData>, State(client): State<AppState>) -> Result<Redirect, PoolError>
在:
async fn handle_form(Form(data): Form<FormData>, State(client): State<AppState<Pool>>) -> Result<Redirect, PoolError>
但现在新的错误是:
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
--> src/main.rs:57:71
|
57 | async fn handle_form(Form(data): Form<FormData>, State(client): State<AppState<Pool>>) -> Result<Redirect, PoolError> {
| ^^^^^^^^------ help: remove these generics
| |
| expected 0 generic arguments
|
note: struct defined here, with 0 generic parameters
--> src/main.rs:26:8
|
26 | struct AppState {
| ^^^^^^^^
这是我的Cargo.toml依赖部分:
[dependencies]
axum = "0.6.18"
tokio = { version = "1.28", features = ["full"] }
tokio-postgres = { version = "0.7.8", features = ["with-uuid-0_8"] }
tower-http = { version = "0.4.0", features = ["cors"] }
serde = { version = "1.0.162", features = ["derive"] }
deadpool-postgres = "0.10.5"
我也试过用“Extension”代替“State”,但情况是一样的。
1条答案
按热度按时间41zrol4v1#
deadpool::managed::errors::PoolError
应转换为其他可以转换为响应的错误类型。full demo code