use std::{env, fs, path::Path}; fn main() { let out_dir = env::var_os("OUT_DIR").unwrap(); { let dest_path = Path::new(&out_dir).join("impl_fn_apply.rs"); fs::write(&dest_path, gen_impl_start() + &gen_impl_extend()).unwrap(); } { let dest_path = Path::new(&out_dir).join("struct_tuple_idx.rs"); fs::write(&dest_path, gen_idx_ty()).unwrap(); } { let dest_path = Path::new(&out_dir).join("impl_tuple_idx.rs"); fs::write(&dest_path, gen_idx_impl()).unwrap(); } println!("cargo::rerun-if-changed=build.rs"); } #[macro_export] macro_rules! mutable { ($name:ident) => { let mut $name = $name; }; } #[macro_export] macro_rules! nonmutable { ($name:ident) => { let $name = $name; }; } fn gen_impl_start() -> String { let o = String::new(); mutable!(o); for i in 1..20 { let mut t = String::new(); for j in 0..=i { t += &format!("T{j}"); if j != i { t += ","; } } o += &format!("impl_applyone!({});\n", t); } o } fn gen_impl_extend() -> String { let mut s = String::new(); for i in 1..20 { for k in 1..=i { let mut t = String::new(); for j in 0..=i { if j == k { t += &format!("[T{j}]"); } else { t += &format!("T{j}"); } if j != i { t += ","; } } s += &format!("impl_extend!({});\n", t); } } s } fn gen_idx_ty() -> String { let mut s = String::new(); for i in 0..20 { s += &format!("/// index tuple by {}\n", i); s += &format!("pub struct I{};\n", i); } s } fn gen_idx_impl() -> String { let o = String::new(); mutable!(o); let len = 20; for i in 0..len { let a = String::new(); mutable!(a); for j in 0..=i { a += &format!("T{}", j); if j != i { a += ", "; } } nonmutable!(a); for j in 0..=i { o += &format!("impls_ref!(I{j}, T{j}, {j}, {a});\n"); o += &format!("impls_mut!(I{j}, T{j}, {j}, {a});\n"); } } o }