The tokio::fs::File::open(path: T + 'static)
requires a 'static
lifetime on its path
parameter.
This makes sense because it is handled in runtime threads during the program's execution. I think it would make more sense if you could pass your own lifetimes, because the runtime does not need to run the whole time and so you could throw away some stuff. Do I understand something wrong?
I'd like to stay for 'static
at the moment and so my problem is this...
I have a trait TraitN
and some struct StructX { path: String, }
with a fn new(path: &String) -> Box<TraitN>
. The new
creates and sets self.path = path.to_string();
.
In some impl fn doit(&self) { ... }
for StructX
, I'd like to call tokio::fs::File::open(&self.path)
.
How can I pass &self.path
with a 'static
lifetime?
This is a complete example:
extern crate futures;
extern crate tokio;
#[macro_use]
extern crate error_chain;
use futures::future;
use futures::future::{loop_fn, ok, Future, Loop};
use futures::Stream;
use std::io::BufReader;
use tokio::{fs, io};
mod error {
error_chain!{}
}
use error::*;
type FutureResult<T> = future::FutureResult<T, Error>;
trait HandlerTrait {
fn new(path: &str) -> Box<HandlerTrait>
where
Self: Sized;
fn get_all(&self) -> FutureResult<Vec<String>>;
}
#[derive(Debug)]
pub struct Handler {
path: String,
}
impl HandlerTrait for Handler {
fn new(path: &str) -> Box<HandlerTrait> {
Box::new(Handler {
path: path.to_string(),
})
}
fn get_all(&self) -> FutureResult<Vec<String>> {
let file = fs::File::open(self.path.clone())
.and_then(|file: fs::File| ok(file))
.wait()
.unwrap();
let lines = io::lines(BufReader::new(file));
ok(lines
.filter(|line| line.len() > 80)
.map(|all| all[0..80].to_string())
.collect()
.wait()
.unwrap())
}
}
fn get_handler(path: &str) -> Option<Box<HandlerTrait>> {
Some(Handler::new(path))
}
fn get_path() -> FutureResult<String> {
ok("./somepath/file".to_string())
}
fn start_runtime() -> Result<()> {
let path: &str = get_path().wait().unwrap().as_str();
tokio::run(doit(path.clone()));
Ok(())
}
fn doit(path: &'static str) -> impl Future<Item = (), Error = ()> + 'static {
let n = 0;
loop_fn(n, move |_nr| {
let lh = get_handler(path).unwrap();
lh.get_all()
.or_else(|_| Err(()))
.and_then(|_all| ok(Loop::Break(())))
})
}
#[test]
fn test() {
start_runtime().unwrap();
assert!(true);
}
error[E0597]: borrowed value does not live long enough
--> src/lib.rs:63:22
|
63 | let path: &str = get_path().wait().unwrap().as_str();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value only lives until here
| |
| temporary value does not live long enough
|
= note: borrowed value must be valid for the static lifetime...