use std::collections::BTreeMap;
use super::{Term, VersionMap};
fn fmt_f(v: f64) -> String {
if (v - v.round()).abs() < 1e-15 {
format!("{v:.1}")
} else {
format!("{v:.14}")
}
}
pub fn generate_modules(versions: &VersionMap) -> anyhow::Result<BTreeMap<char, String>> {
let coord_letter = |c| match c {
1 => 'X',
2 => 'Y',
3 => 'Z',
_ => '?',
};
let mut modules = BTreeMap::new();
for (version, planets) in versions {
let mut code = String::new();
code.push_str("// ---------------------------------------------------\n");
code.push_str("// **AUTOGENERATED** by build.rs – DO NOT EDIT BY HAND\n");
code.push_str("// ---------------------------------------------------\n");
code.push_str("use crate::calculus::vsop87::vsop87_impl::Vsop87;\n\n");
for (planet, coords) in planets {
let planet_up = planet.to_uppercase();
for (coord, t_powers) in coords {
let letter = coord_letter(*coord);
for (t, terms) in t_powers {
let array_name = format!("{planet_up}_{letter}{t}");
code.push_str("#[allow(dead_code)]\n");
code.push_str(&format!(
"pub static {array_name}: [Vsop87; {}] = [\n",
terms.len()
));
for Term { a, b, c } in terms {
code.push_str(&format!(
" Vsop87 {{ a: {}, b: {}, c: {} }},\n",
fmt_f(*a),
fmt_f(*b),
fmt_f(*c)
));
}
code.push_str("]\n;\n\n");
}
}
}
modules.insert(*version, code);
}
Ok(modules)
}