Reputation: 1358
In the below example, I have parameters verbose
and data_source
that are set by command line parameters. verbose
is a boolean flag, but data_source
is used to select a default from a set of available functions that can be used depending on the data source for the application.
Actix uses a closure to set up a server, so I need to get these parameters into the closure. I added move
for the bool, but I'm having trouble passing in the function to be used for the index and am getting lifetime errors. I've tried boxing the function, but that doesn't seem to help.
If I'm understanding the error message correctly, it's actually the closure itself that is failing to outlive 'static
.
What should I do to solve this issue?
extern crate actix;
extern crate actix_web;
extern crate env_logger;
use actix_web::http::Method;
use actix_web::{middleware, server, App, HttpRequest, HttpResponse};
enum DataSource {
Postgres,
HDF5,
}
fn index_postgres(req: &HttpRequest) -> HttpResponse {
HttpResponse::Ok().body("not implemented")
}
fn index_hdf5(req: &HttpRequest) -> HttpResponse {
HttpResponse::Ok().body("not implemented")
}
fn main() {
let mut verbose = false;
verbose = true;
let mut data_source = DataSource::Postgres;
data_source = DataSource::HDF5;
let index = match data_source {
DataSource::Postgres => index_postgres,
DataSource::HDF5 => index_hdf5,
};
::std::env::set_var("RUST_LOG", "actix_web=info");
env_logger::init();
let sys = actix::System::new("test");
server::new(move || {
if verbose {
App::new()
.middleware(middleware::Logger::default())
.resource("/", |r| r.method(Method::GET).f(index))
} else {
App::new().resource("/", |r| r.method(Method::GET).f(index))
}
})
.bind("127.0.0.1:8080")
.unwrap()
.start();
println!("Started http server: 127.0.0.1:8080");
let _ = sys.run();
}
error: unsatisfied lifetime constraints
--> src\main.rs:50:13
|
48 | server::new(move || {
| ------- lifetime `'1` represents this closure's body
49 | if verbose {
50 | / App::new()
51 | | .middleware(middleware::Logger::default())
52 | | .resource("/", |r| r.method(Method::GET).f(index))
| |__________________________________________________________________^ argument requires that `'1` must outlive `'static`
|
= note: closure implements `Fn`, so references to captured variables can't escape the closure
Upvotes: 1
Views: 382
Reputation: 12908
I don't understand what compiler is trying to say but it obvious that you need move
in handler closures:
if verbose {
App::new()
.middleware(middleware::Logger::default())
.resource("/", move |r| r.method(Method::GET).f(index))
} else {
App::new().resource("/", move |r| r.method(Method::GET).f(index))
}
This is because you need to move index
from the outer closure.
Upvotes: 1