Rust 如何使用include_str!对于多个文件还是整个目录?
我想将整个目录复制到用户的Rust 如何使用include_str!对于多个文件还是整个目录?,rust,Rust,我想将整个目录复制到用户的$HOME中的某个位置。将文件单独复制到该目录非常简单: let contents = include_str!("resources/profiles/default.json"); let fpath = dpath.join(&fname); fs::write(fpath, contents).expect(&format!("failed to create profile: {}", n)); 我还没有找到一种方法来适应多个文件: for
$HOME
中的某个位置。将文件单独复制到该目录非常简单:
let contents = include_str!("resources/profiles/default.json");
let fpath = dpath.join(&fname);
fs::write(fpath, contents).expect(&format!("failed to create profile: {}", n));
我还没有找到一种方法来适应多个文件:
for n in ["default"] {
let fname = format!("{}{}", n, ".json");
let x = format!("resources/profiles/{}", fname).as_str();
let contents = include_str!(x);
let fpath = dpath.join(&fname);
fs::write(fpath, contents).expect(&format!("failed to create profile: {}", n));
}
…编译器抱怨x
必须是字符串文本
据我所知,有两种选择:
use std::{
env,
error::Error,
fs::{self, File},
io::Write,
path::Path,
};
const SOURCE_DIR: &str = "some/path/to/include";
fn main() -> Result<(), Box<dyn Error>> {
let out_dir = env::var("OUT_DIR")?;
let dest_path = Path::new(&out_dir).join("all_the_files.rs");
let mut all_the_files = File::create(&dest_path)?;
writeln!(&mut all_the_files, r##"["##,)?;
for f in fs::read_dir(SOURCE_DIR)? {
let f = f?;
if !f.file_type()?.is_file() {
continue;
}
writeln!(
&mut all_the_files,
r##"("{name}", include_bytes!(r#"{name}"#)),"##,
name = f.path().display(),
)?;
}
writeln!(&mut all_the_files, r##"]"##,)?;
Ok(())
}
另见:
macro_rules! incl_profiles {
( $( $x:expr ),* ) => {
{
let mut profs = Vec::new();
$(
profs.push(($x, include_str!(concat!("resources/profiles/", $x, ".json"))));
)*
profs
}
};
}
让prof_tups:Vec=incl_profile!(“默认”、“python”);
对于prof_tups中的(prof_name,prof_str){
设fname=format!(“{}{}”,prof_name,“.json”);
让fpath=dpath.join(&fname);
fs::write(fpath,prof_str).expect(&format!(&failed to create profile:{},prof_name));
}
注意:这不是动态的。这些文件(“default”和“python”)是在对宏的调用中指定的
更新:使用
Vec
而不是HashMap
如果您只想进行迭代,那么使用HashMap
是不必要的开销。@Shepmaster正在使用它,所以我不需要另一行“default”
和“python”
。。。我想我可以使用一个数组,然后将其拆分,但这似乎更简单。你会推荐什么?如我的答案所示的元组数组([(名称,值)]
)。嗨,我不知道这是否仍然是首选的方法,但是当我尝试这个方法时(在{projectRoot}/build.rs
中的第一个片段,在{projectRoot}/src/main.rs
)中的第二个片段抱怨它找不到文件。我猜如果constsource\u DIR:&str=“some/path/to/include”
是一个绝对路径,它可以工作,但是使用绝对路径对于分发来说并不好。我还遗漏了什么吗?@DavSanchez确实向您展示了如何将SOURCE\u DIR
替换为与您的项目相关的内容?是的,我尝试过,它通过删除也起到了作用代码>来自上次写入时的原始字符串n!()
的build.rs
。谢谢!
macro_rules! incl_profiles {
( $( $x:expr ),* ) => {
{
let mut profs = Vec::new();
$(
profs.push(($x, include_str!(concat!("resources/profiles/", $x, ".json"))));
)*
profs
}
};
}
let prof_tups: Vec<(&str, &str)> = incl_profiles!("default", "python");
for (prof_name, prof_str) in prof_tups {
let fname = format!("{}{}", prof_name, ".json");
let fpath = dpath.join(&fname);
fs::write(fpath, prof_str).expect(&format!("failed to create profile: {}", prof_name));
}