use std::env; use std::path::{Path, PathBuf}; use std::fs::{self, File}; use std::io::{self, Read, Write}; fn list_files< P: AsRef< Path > >( path: P ) -> io::Result< Vec< PathBuf > > { let mut output = Vec::new(); for entry_opt in try!( fs::read_dir( path.as_ref() ) ) { let entry = entry_opt?; let metadata = fs::metadata( entry.path() )?; if metadata.is_dir() { continue; } else { output.push( entry.path() ) } } Ok( output ) } fn main() { let files = list_files( "src/tests" ).unwrap(); let mut modules: Vec< _ > = files.into_iter().flat_map( |path| { let filename = path.file_name().unwrap().to_string_lossy(); if filename.starts_with( "test_" ) == false { None } else { Some( filename[ 0..filename.len() - 3 ].to_owned() ) } }).collect(); modules.sort(); let out_dir: PathBuf = env::var_os( "CARGO_MANIFEST_DIR" ).unwrap().into(); let out_filename = out_dir.join( "src" ).join( "tests" ).join( "mod.rs" ); let mut out = Vec::new(); writeln!( out, "// This file was AUTOGENERATED; do not edit!" ).unwrap(); writeln!( out, "" ).unwrap(); for module_name in &modules { writeln!( out, "mod {};", module_name ).unwrap(); } writeln!( out, "" ).unwrap(); for module_name in &modules { writeln!( out, "pub use tests::{}::*;", module_name ).unwrap(); } writeln!( out, "" ).unwrap(); writeln!( out, "#[macro_export]" ).unwrap(); writeln!( out, "macro_rules! rp2c02_testsuite {{" ).unwrap(); writeln!( out, " ($interface:ident) => (" ).unwrap(); writeln!( out, " mod rp2c02_testsuite {{" ).unwrap(); for module_name in &modules { writeln!( out, " #[test]" ).unwrap(); writeln!( out, " fn {}() {{", module_name ).unwrap(); writeln!( out, " use super::$interface;" ).unwrap(); writeln!( out, " let mut ppu = $interface::new();" ).unwrap(); writeln!( out, " $crate::tests::{}( &mut ppu );", module_name ).unwrap(); writeln!( out, " }}" ).unwrap(); } writeln!( out, " }}" ).unwrap(); writeln!( out, " )" ).unwrap(); writeln!( out, "}}" ).unwrap(); if let Ok( mut fp ) = File::open( &out_filename ) { let mut old_contents = Vec::new(); if let Ok( _ ) = fp.read_to_end( &mut old_contents ) { if old_contents == out { return; // Nothing changed; no point in writing to disk. } } } let mut fp = File::create( out_filename ).unwrap(); fp.write_all( &out[..] ).unwrap(); }