use yog_mirror::host::{ALL, HostMirror};
pub(super) const CLASS: &str = "YogMirrors";
fn class_of(m: &HostMirror) -> String {
let path = m.address.strip_prefix(yog_ids::host_mirror::PREFIX).unwrap_or(m.address);
path.split(yog_ids::sep::PATH).map(super::class_name).collect()
}
fn mirror(m: &HostMirror) -> String {
let mut out = format!(
"\n /** {address} (`yog_mirror::host`). */\n public static final class {class} {{\n private {class}() {{}}\n\n public static final String ADDRESS = \"{address}\";\n public static final String SPACE = \"{space}\";\n",
address = m.address,
class = class_of(m),
space = m.space,
);
for (i, f) in m.fields.iter().enumerate() {
out.push_str(&format!(
" /** Field `{}` ({:?} × {}): its index, its bit is {{@code 1L << index}}. */\n public static final int {} = {i};\n",
f.name,
f.kind,
f.count,
f.name.to_uppercase()
));
}
out.push_str(" }\n");
out
}
fn traits() -> String {
let mut out = String::from(
"\n /** A block's traits (`yog_ids::block_trait`): each one's bit index. */\n public static final class BlockTrait {\n private BlockTrait() {}\n\n",
);
for (i, name) in yog_ids::block_trait::ALL_VALUES.iter().enumerate() {
out.push_str(&format!(
" public static final int {} = {i};\n",
name.to_uppercase()
));
}
out.push_str(" }\n");
out
}
pub(super) fn file(package: &str) -> String {
let body: String = ALL.iter().map(|m| mirror(m)).collect::<String>() + &traits();
format!(
"// Generated by yog-event-export from yog_mirror::host — don't edit.\npackage {package};\n\n/** The host's mirrors: their addresses, key spaces and fields. */\npublic final class {CLASS} {{\n private {CLASS}() {{}}\n{body}}}\n"
)
}