如何使用include宏从单个文件加载多个元素?

时间:2019-06-13 14:51:40

标签: rust

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);
}

问题是我的字符串放在文件中:

file.in:

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

我无法更改文件的内容。如何将include! / include_str!与宏vec_strs一起使用,以将元素从file.in加载到向量中?预先感谢。

1 个答案:

答案 0 :(得分:0)

对此没有任何一步的解决方案。 include!宏假定它将从文件加载格式完整的Rust语法,而您的文件不是。

最接近的是build script。这样,您可以解析任何种类的输入并生成任何种类的输出。

因为您的代码几乎是 一个文字数组,所以最便宜的方法是在其周围添加方括号:

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(())
}

然后您可以直接导入该数组:

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

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

当然,您可以更改构建脚本以适合您的需求。例如,您可以生成对宏的调用,然后导入包含宏调用的文件。

另请参阅:


作为奖励,应该编写宏以利用vec!的优势,macro_rules! vec_strs { ($($element:expr),*) => { vec![$($element.to_string()),*] }; } 使用一些编译器内部组件可以提高效率:

java -jar  -Dwebdriver.gecko.driver=geckodriver selenium-server-standalone-3.141.59.jar -log logs/selenium.log > logs/output.log 2>&1 &