1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
//! Provides the directory of the executable. use std::{env, io, path}; /// Returns the cargo manifest directory when running the executable with cargo or the directory in /// which the executable resides otherwise, traversing symlinks if necessary. /// /// The algorithm used is: /// /// * If the `CARGO_MANIFEST_DIR` environment variable is defined it is used as application root. /// This simplifies running development projects through `cargo run`. /// See the [cargo reference documentation][cargo-ref] for more details. /// * If the executable name can be found using [`std::env::current_exe`], resolve all symlinks and /// use the directory it resides in as application root. /// /// If none of the above works, an error is returned. /// /// [cargo-ref]: https://doc.rust-lang.org/cargo/reference/environment-variables.html /// [`std::env::current_exe`]: https://doc.rust-lang.org/std/env/fn.current_exe.html pub fn application_root_dir() -> Result<path::PathBuf, io::Error> { if let Some(manifest_dir) = env::var_os("CARGO_MANIFEST_DIR") { return Ok(path::PathBuf::from(manifest_dir)); } let mut exe = env::current_exe()?.canonicalize()?; // Modify in-place to avoid an extra copy. if exe.pop() { return Ok(exe); } Err(io::Error::new( io::ErrorKind::Other, "Failed to find an application root", )) } /// Same as `application_root_dir`, but extends the root directory with the given path. pub fn application_dir<P>(path: P) -> Result<path::PathBuf, io::Error> where P: AsRef<path::Path>, { Ok(application_root_dir()?.join(path)) }