将移动的变量重新用于 warp 过滤器
Reusing a moved variable for warp filters
我想使用 Rust 和 Juniper 创建一个 GraphQL 服务器。此服务器必须访问数据库。
我一直在尝试关注 Juniper 的 this example code,但它使用空的 Context
来让位于 Schema
;我需要为数据库连接发送一个池。
我希望能够通过 POST
、GET
和 websockets 连接到 GraphQL。
type RepositoryPool = r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>;
fn graphql(
db_pool: RepositoryPool,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
let state = warp::any().map(move || Context::new(db_pool.clone()));
let root_node = Arc::new(schema());
let graphql_filter = make_graphql_filter(schema(), state.boxed());
let post_filter = warp::post()
.and(warp::body::content_length_limit(1024 * 16))
.and(graphql_filter.clone());
let get_filter = warp::get().and(graphql_filter);
let ws_filter = warp::ws().map(move |ws: warp::ws::Ws| {
let root_node = root_node.clone();
let db_pool = db_pool.clone();
ws.on_upgrade(move |websocket| async move {
serve_graphql_ws(
websocket,
root_node,
ConnectionConfig::new(Context::new(db_pool)),
)
.map(|r| {
if let Err(e) = r {
println!("Websocket error: {}", e);
}
})
.await
})
});
warp::path("graphql").and(get_filter.or(post_filter).or(ws_filter))
}
但是,我得到一个错误:
error[E0382]: use of moved value: `db_pool`
--> src\filters.rs:39:34
|
27 | db_pool: RepositoryPool,
| ------- move occurs because `db_pool` has type `r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>`, which does not implement the `Copy` trait
28 | ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
29 | let state = warp::any().map(move || Context::new(db_pool.clone()));
| ------- ------- variable moved due to use in closure
| |
| value moved into closure here
...
39 | let ws_filter = warp::ws().map(move |ws: warp::ws::Ws| {
| ^^^^^^^^^^^^^^^^^^^^^^^ value used here after move
40 | let root_node = root_node.clone();
41 | let db_pool = db_pool.clone();
| ------- use occurs due to use in closure
我对这些值 move
d 解决此问题的方式了解不够。我该如何解决此类问题?
感谢一些评论,我找到了 Rust 编译器接受的方式:
fn graphql(
db_pool: RepositoryPool,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
let db_pool_clone = db_pool.clone();
let state = warp::any().map(move || Context::new(db_pool_clone.clone()));
let root_node = Arc::new(schema());
let graphql_filter = make_graphql_filter(schema(), state.boxed());
let post_filter = warp::post()
.and(warp::body::content_length_limit(1024 * 16))
.and(graphql_filter.clone());
let get_filter = warp::get().and(graphql_filter);
let ws_filter = warp::ws().map(move |ws: warp::ws::Ws| {
let root_node = root_node.clone();
let db_pool = db_pool.clone();
ws.on_upgrade(move |websocket| async move {
serve_graphql_ws(
websocket,
root_node,
ConnectionConfig::new(Context::new(db_pool)),
)
.map(|r| {
if let Err(e) = r {
println!("Websocket error: {}", e);
}
})
.await
})
});
warp::path("graphql").and(get_filter.or(post_filter).or(ws_filter))
}
我不完全明白为什么这是必要的,但现在可以。
我想使用 Rust 和 Juniper 创建一个 GraphQL 服务器。此服务器必须访问数据库。
我一直在尝试关注 Juniper 的 this example code,但它使用空的 Context
来让位于 Schema
;我需要为数据库连接发送一个池。
我希望能够通过 POST
、GET
和 websockets 连接到 GraphQL。
type RepositoryPool = r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>;
fn graphql(
db_pool: RepositoryPool,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
let state = warp::any().map(move || Context::new(db_pool.clone()));
let root_node = Arc::new(schema());
let graphql_filter = make_graphql_filter(schema(), state.boxed());
let post_filter = warp::post()
.and(warp::body::content_length_limit(1024 * 16))
.and(graphql_filter.clone());
let get_filter = warp::get().and(graphql_filter);
let ws_filter = warp::ws().map(move |ws: warp::ws::Ws| {
let root_node = root_node.clone();
let db_pool = db_pool.clone();
ws.on_upgrade(move |websocket| async move {
serve_graphql_ws(
websocket,
root_node,
ConnectionConfig::new(Context::new(db_pool)),
)
.map(|r| {
if let Err(e) = r {
println!("Websocket error: {}", e);
}
})
.await
})
});
warp::path("graphql").and(get_filter.or(post_filter).or(ws_filter))
}
但是,我得到一个错误:
error[E0382]: use of moved value: `db_pool`
--> src\filters.rs:39:34
|
27 | db_pool: RepositoryPool,
| ------- move occurs because `db_pool` has type `r2d2::Pool<diesel::r2d2::ConnectionManager<diesel::PgConnection>>`, which does not implement the `Copy` trait
28 | ) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
29 | let state = warp::any().map(move || Context::new(db_pool.clone()));
| ------- ------- variable moved due to use in closure
| |
| value moved into closure here
...
39 | let ws_filter = warp::ws().map(move |ws: warp::ws::Ws| {
| ^^^^^^^^^^^^^^^^^^^^^^^ value used here after move
40 | let root_node = root_node.clone();
41 | let db_pool = db_pool.clone();
| ------- use occurs due to use in closure
我对这些值 move
d 解决此问题的方式了解不够。我该如何解决此类问题?
感谢一些评论,我找到了 Rust 编译器接受的方式:
fn graphql(
db_pool: RepositoryPool,
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
let db_pool_clone = db_pool.clone();
let state = warp::any().map(move || Context::new(db_pool_clone.clone()));
let root_node = Arc::new(schema());
let graphql_filter = make_graphql_filter(schema(), state.boxed());
let post_filter = warp::post()
.and(warp::body::content_length_limit(1024 * 16))
.and(graphql_filter.clone());
let get_filter = warp::get().and(graphql_filter);
let ws_filter = warp::ws().map(move |ws: warp::ws::Ws| {
let root_node = root_node.clone();
let db_pool = db_pool.clone();
ws.on_upgrade(move |websocket| async move {
serve_graphql_ws(
websocket,
root_node,
ConnectionConfig::new(Context::new(db_pool)),
)
.map(|r| {
if let Err(e) = r {
println!("Websocket error: {}", e);
}
})
.await
})
});
warp::path("graphql").and(get_filter.or(post_filter).or(ws_filter))
}
我不完全明白为什么这是必要的,但现在可以。