0
macro_rules! vec_strs {
    (
        $($element:expr),*
    ) => {
        {
            let mut v = Vec::new();
            $(
                v.push(format!("{}", $element));
            )*
            v
        }
    };
}

fn main() {
    let v = vec_strs!("1", "2");
    println!("{}", v);
}

The problem is that my strings are placed in a file:

file.in:

"first", "second", "third", .... 

I cannot change the content of the file. How can I use include!/include_str! with my macro vec_strs to "load" elements to the vector from file.in? Thanks in advance.

Gilgamesz
  • 4,727
  • 3
  • 28
  • 63
J. Doe
  • 65
  • 6

1 Answers1

0

There is no one-step solution to this. The include! macro assumes that it will load fully-formed Rust syntax from a file and your file is not that.

The closest thing is a build script. With this, you can parse any kind of input and generate any kind of output.

Since your code is almost a literal array, the cheapest thing you can do is to add square brackets around it:

build.rs

use std::{
    env,
    fs::File,
    io::{self, Write},
    path::PathBuf,
};

fn main() -> Result<(), Box<std::error::Error>> {
    let mut src = File::open("file.in")?;

    let out_dir: PathBuf = env::var_os("OUT_DIR").ok_or("Cannot find OUT_DIR")?.into();
    let out_file = out_dir.join("file.in.rs");
    let mut out = File::create(out_file)?;

    write!(&mut out, "[")?;
    io::copy(&mut src, &mut out)?;
    write!(&mut out, "]")?;

    Ok(())
}

You can then just import that array directly:

const STRINGS: &[&str] = &include!(concat!(env!("OUT_DIR"), "/file.in.rs"));

fn main() {
    for s in STRINGS {
        println!("{}", s);
    }
}

You can, of course, change the build script to suit your needs. For example, you could generate a call to your macro and then import the file containing the macro call.

See also:


As a bonus, your macro should be written to take advantage of vec!, which uses some compiler internals to be more efficient:

macro_rules! vec_strs {
    ($($element:expr),*) => {
        vec![$($element.to_string()),*]
    };
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366