5

Is there a Rust macro or a similar workaround to include the path of the 'src' folder created via cargo new in my source file as a string literal at compile time or specifically when doing cargo build?

I have successfully done something similar where I use include_str! to include file content but I need to know if it is possible to directly include the src path in the code.

Harindaka
  • 4,658
  • 8
  • 43
  • 62

2 Answers2

7

No, but you can get close using file!:

const FILE: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/", file!());

fn main() {
    use std::path::Path;

    println!("FILE: {:?}", FILE);
    println!("src path: {:?}", Path::new(FILE).parent());
}

Outputs, on the playground:

FILE: "/playground/src/main.rs"
src path: Some("/playground/src")
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
DK.
  • 55,277
  • 5
  • 189
  • 162
0

As @DK mentioned this can be done with file!() and env!("CARGO_MANIFEST_DIR").

Here's a macro for ease of use:

#[macro_export]
macro_rules! file_abs {
    () => {
        std::path::Path::new(env!("CARGO_MANIFEST_DIR").join(file!()))
    };
}

Workspace Crates

This solution works for standalone crates but not workspaces. Assuming the crate is following the standard convention of crates/my_crate the above macro would return something like this:

/playgroud/crates/my_crate/crates/my_crate/src/main.rs

This can be fixed by popping the first two components of the path returned by file!().


#[macro_export]
macro_rules! file_abs_workspace {
    () => {
        std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
            .join(my_crate::pop_first_two_path_components(file!()))
    };
}

pub fn pop_first_two_path_components(path: &str) -> PathBuf {
    let mut components = std::path::Path::new(path).components();
    components.next();
    components.next();
    components.as_path().to_path_buf()
}

Once you have the file you can get the parent like normal:


fn main(){
  let dir = file_abs_workspace!().parent().unwrap();
  println!("directory is: {:?}", dir);
}

Note i haven't yet tried this with a published workspace crate, I suspect in that case you'd need to switch back to file_abs!().

chantey
  • 4,252
  • 1
  • 35
  • 40