1
votes

I'm kinda new to the concept of how Rust works even after experimenting with it for a couple months. I'm writing a webserver with R2D2 (0.8.0) and Rocket (0.4.4) + Rocket_cors (0.5.2)

Rocket allows you to feed it structs into a state pool, so I don't have to initialize my Postgres server every time somebody sends a request. Here's the code:

struct ConnectionPool<M: r2d2::ManageConnection> {
    val: r2d2::Pool<M>
}

#[post("/upload", format = "application/json", data = "<data>")]
fn upload(data: Data, state: rocket::State<ConnectionPool>) {
    if data.peek_complete() {
        println!("All of the data: {:?}", str::from_utf8(data.peek()).unwrap());
    }
    //data.stream_to_file(env::temp_dir().join("upload.txt"))
    //    .map(|n| n.to_string())
    //    .map_err(Debug)
}

Obviously, this is just a snippet of the code, but r2d2::ConnectionPool requires one type identifier: giving me this error if I ignore the requirement (on line 4 in the code snippet above):

wrong number of type arguments: expected 1, found 0

expected 1 type argumentrustc(E0107)
main.rs(45, 44): expected 1 type argument

But when I try my best-ish to solve the problem by updating the code:

fn upload(data: Data, state: rocket::State<ConnectionPool>) {

    |
    v

fn upload(data: Data, state: rocket::State<ConnectionPool<r2d2::ManageConnection>>) {

I get this error:

the size for values of type `(dyn r2d2::ManageConnection + 'static)` cannot be known at compilation time

doesn't have a size known at compile-time

help: the trait `std::marker::Sized` is not implemented for `(dyn r2d2::ManageConnection + 'static)`
1
r2d2::ManageConnection is a trait. You need to specifiy the actual, concrete connection type you are using. You didn't share the code creating the connection pool, so we can't tell you what that type is. - Sven Marnach

1 Answers

1
votes

r2d2::ManageConnection is a trait. Rather than repeating the trait name you need to pass it a concrete type that implements the trait. Since you're using Postgres you probably want:

fn upload(data: Data, state: rocket::State<ConnectionPool<PostgresConnectionManager>>)

Alternatively, if you want to keep your code database agnostic you can make the method generic over the connection type and let the caller decide:

fn upload<M: r2d2::ManageConnection>(data: Data, state: rocket::State<ConnectionPool<M>>)