Hi Rustaceans,
I'm an experienced coder but in early man-weeks with Rust.
I'm trying to build a simple REST server and keep hitting roadblocks.
I'm probably making some newb-ish mistake but can't seem to spot it.
MUCH THANKS to those that give me a boost.
I think what I want is:
- main() configres a deadpool-postgres pool and warp filter
- warp__server() sends a request to do_jump() including the pool
- do_jump() gets a client connection from the pool and does database things
The code provided is the simplest version of the many approaches I've tried.
use deadpool_postgres::{Manager, ManagerConfig, Pool, RecyclingMethod};
use tokio_postgres::{NoTls};
use warp::Filter;
#[tokio::main]
async fn main()
{
let mut pg_config = tokio_postgres::Config::new();
pg_config.host("localhost");
pg_config.user("cards2");
pg_config.password("cards2");
pg_config.dbname("cards2");
let mgr_config = ManagerConfig {
recycling_method: RecyclingMethod::Fast
};
let mgr = Manager::from_config(pg_config, NoTls, mgr_config);
let pool = Pool::builder(mgr).max_size(16).build().unwrap();
for i in 1..10 {
let client = pool.get().await.unwrap();
let stmt = client.prepare_cached("SELECT 1 + $1").await.unwrap();
let rows = client.query(&stmt, &[&i]).await.unwrap();
let value: i32 = rows[0].get(0);
println!("{} {}", i, value);
assert_eq!(value, i + 1);
}
let jump_filter = warp::path("jump")
.and(pool.clone())
.and_then(do_jump);
warp::serve(jump_filter)
.run(([127, 0, 0, 1], 3030))
.await;
}
pub async fn do_jump(pool: deadpool_postgres::Pool) -> Result<impl warp::Reply, warp::Rejection>
{
println!("running do_jump()");
let client = pool.get().await.unwrap();
//do database things
let foo = "foo".to_string();
Ok(warp::reply::html(foo))
}
It fails to compile with:
> 29 | .and(pool.clone())
> | ^^^^^^^^^^^^ the trait `warp::filter::FilterBase` is not implemented for `deadpool::managed::Pool<Manager>`
>
> error[E0599]: the method `and_then` exists for struct `warp::filter::and::And<Exact<warp::path::internal::Opaque<&str>>, deadpool::managed::Pool<Manager>>`, but its trait bounds were not satisfied
> --> cards_db_test/src/main.rs:30:10
> |
> 30 | .and_then(do_jump);
> | ^^^^^^^^ method cannot be called on `warp::filter::and::And<Exact<warp::path::internal::Opaque<&str>>, deadpool::managed::Pool<Manager>>` due to unsatisfied trait bounds
My Cargo.toml:
[package]
name = "cards_db_test"
version = "0.1.0"
edition = "2021"
[dependencies]
warp = "0.3.2"
tokio = { version = "1.17.0", features = ["full"]}
tokio-postgres = {version = "0.7.5", features = ["with-serde_json-1"] }
deadpool-postgres = "0.10.2"
This impl runs afoul of warp's generic processing and privacy choices.
Other approaches run afoul of policies on global variables, or static initializers
or lazy_statics or futures or manual drops or macro processing.
I even tried a union to init a global early, then give it real values later on.
I guess you could say I'm trying to find a general way to create subsystems in
my code that each require some global state.
I'd welcome a solution to the above code,
but more so a better understanding of how a smart Rustacean should do this.
While this is frustrating, I guess I should admire the thoroughness of the compiler.
Best wishes to all!