如何仅在模块存在的情况下导入模块



我正在做代码的出现,这是25个编程问题的集合,出现的每一天都有一个。

我在它自己独立的文件/模块中构建每一天,所以例如2021年的第7天将在src/years/year2021/day07.rs。所以src/years/year2021/mod.rs最终只是pub mod

pub mod day01;
pub mod day02;
pub mod day04;
// and so on...

有没有一种方法可以动态生成这个列表(用递归宏之类的东西),所以检查模块day01是否可以从这个上下文访问(或者如果./day01.rs存在),并自动生成pub mod,并在创建文件时添加更多。

最好的是能够检查是否存在任何名称,比如模块或模块内的函数。

您可以使用build.rs根据构建时存在的文件生成模块。

像这个漂亮的

let years_path = path::Path::new("./src/years");
let mut mod_file = fs::File::create(years_path.join("mod.rs")).unwrap();
let paths = fs::read_dir(years_path).unwrap();
for entry in paths {
let entry = entry.unwrap();
if entry.metadata().unwrap().is_dir() {
writeln!(
mod_file,
"mod {};",
entry.path().file_name().unwrap().to_str().unwrap()
)
.unwrap();
}
}

我使用的build.rs版本与@pidgeonhands-one非常相似。它对文件夹中的奇怪文件更有弹性(只有在无法创建或写入文件时才会崩溃),并且可以工作多年:

use std::{
error::Error,
ffi::OsString,
fs::{self, File},
io::Write,
path::Path,
};
fn main() -> Result<(), Box<dyn Error>> {
println!("cargo:rerun-if-changed=src/years");
let years_path = Path::new("src/years");
let mut years_mod_file = File::create(years_path.join("mod.rs"))?;
for year in fs::read_dir("src/years")? {
let Ok(year) = year else {continue};
let year_name = year.file_name();
let Some(year_name) = year_name.to_str() else {continue};
if year_name != OsString::from("mod.rs") {
writeln!(years_mod_file, "pub mod {year_name};")?;
let mut year_mod_file = File::create(year.path().join("mod.rs"))?;
for day in fs::read_dir(year.path())? {
let Ok(day) = day else {continue};
if day.file_name() != OsString::from("mod.rs") {
let day_name = day.path();
let Some(day_name) = day_name.file_stem() else {continue};
let Some(day_name) = day_name.to_str() else {continue};
writeln!(year_mod_file, "pub mod {day_name};")?;
println!("{:?}", day_name);
}
}
}
}
Ok(())
}

相关内容

最新更新