rust 如何仅在模块存在时才导入它们?

hec6srdp  于 2023-01-13  发布在  其他
关注(0)|答案(2)|浏览(123)

我正在做代码的出现,这是一个25个编程问题的集合,每个问题对应一天的出现。
我将每一天组织在它自己的单独文件/模块中,例如2021年的第7天将是src/years/year2021/day07.rs,因此src/years/year2021/mod.rs最终只是pub mod s

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

有没有一种方法可以动态生成这个列表(使用类似递归宏的东西),所以检查模块day 01是否可以从这个上下文访问(或者./ www.example.com是否day01.rs存在),并自动生成pub mod,并在创建文件时添加更多。
最好的方法是检查是否存在任何名称,比如模块或模块内的函数。

ujv3wf0j

ujv3wf0j1#

您可以使用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();
    }
}
6jjcrrmo

6jjcrrmo2#

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

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

相关问题