How do I get a static path for tokio::fs::File::open?

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...

playground

open file on the filesystem. This is a specialized version of std::fs::File for usage from the Tokio runtime. pub fn open<P>(path: P) -> OpenFuture<P> where print app.static_url_path I get the correct static_url_path. But in my templates when I use url_for('static'), The html file generated using jinja2 still has the default static URL path /static with the missing PREFIX that I added. If I hardcode the path like this: app = Flask(__name__, static_url_path='PREFIX/static') It works fine.

You can restrict the lifetime of &self:

impl StructX {
    fn doit(&'static self) {
        // here, we know that self and its members are 'static
    }
}

If you do this, you may actually be better off to have StructX store the 'static borrow of the path in the first place (instead of a string).

pub fn open<P>(path: P) -> OpenFuture<P> where. P: AsRef<Path> + Send + '​static,. [src]. [−]. Attempts to open a file in read-only mode. @bartlomieju I was able to do all of them except the ones I mentioned (chown, utime, with mkdir/makeTemp up in the air).. My ftruncate etc ops (still in the queue for #4017, waiting for other PRs to be merged first) use the nix crate, so they mostly don't have tokio correlates, so they're written instead like this:

where P: AsRef<Path> + Send + 'static,. {. OpenFuture::new(path). OpenOptions::​new().read(true).open(path). } /// Opens a file in write-only mode. ///. I believe the above piece will get the Filewhne it is either placed inside the application or if the code is run on local machine. But if my code is in some server and i want to get the file from my local machine in the code. How can we do that?

34 changed files 1,605 additions and 260 deletions. tokio-fs/Cargo.toml static ref POOL: tokio_threadpool::ThreadPool = { tokio-fs/src/file/open.rs  The path parameter may specify relative or absolute path information. Relative path information is interpreted as relative to the current working directory. To obtain the current working directory, use the GetCurrentDirectory method. The returned FileStream does not support reading. To open a file for both reading and writing, use Open.

pub async fn open(path: impl AsRef<Path>) -> Result<File> [src][−] use tokio::fs​::File; use tokio::prelude::*; let mut file = File::open("foo.txt").await?; let mut  The returned read-only span contains the characters of the path that follow the last separator in path. If the last character in path is a volume or directory separator character, the method returns ReadOnlySpan<T>.Empty. If path contains no separator character, the method returns path. See also. File path formats on Windows systems

open file on the filesystem. This is a specialized version of std::fs::File for usage from the Tokio runtime. pub fn open<P>(path: P) -> OpenFuture<P> where Django Static Files Handling made Simple – Even your Kids can do it! by DataFlair Team · Updated · June 3, 2019 Today, websites have become much more interactive than ever.

Comments
  • Please review how to create a minimal reproducible example and then edit your question to include it. We cannot tell what crates, types, traits, fields, etc. are present in the code. Try to produce something that reproduces your error on the Rust Playground or you can reproduce it in a brand new Cargo project. There are Rust-specific MCVE tips as well.
  • Why is it discouraged to accept a reference to a String (&String), Vec (&Vec) or Box (&Box) as a function argument?.
  • Mmh. Do I have not tried the cloning, because the compiler was talking about lifetimes? I'm not sure. I'll see.
  • I'm sorry, but the clone doesn't work. open() wants to have a 'static - Perhaps you can show me, how you can implement fn make_static_str<'a>(s: &'a str) -> &'static str;
  • @Markus fn make_static_str<'a>(s: &'a str) -> &'static str. please search for existing questions: How to convert a String into a &'static str. However, as I commented, doing so is usually a very bad idea.
  • Ok, I understand this, but I don't know how I should create a future for tokio::run() and how the clone should work, when there are everywhere 'static requirements. The clone of &str is a &str and not a &'static str?!
  • I've updated the question with a link to rust playground.
  • I would prefer the later, but I don't know how this can be done, because I need some place to make a dynamic string to a static one. Maybe the StructX is the place?! Don't know if this is the rust way or there is a better possibility?!
  • Not sure... Is it possible to get a static return type, if I move something non-static in?
  • While this is technically true, it's mostly useless as there's very few ways to create a structure that meet the requirements without doing terrible things to the rest of the program, like leaking memory.