yog-event 0.10.1

Yog event system — pub/sub for game/server events.
Documentation
//! `YogMirrors`: the host's mirrors for the Java host that writes them —
//! each one's address, key space and field indices, from their one source
//! (`yog_mirror::host`).

use yog_mirror::host::{ALL, HostMirror};

/// The generated class.
pub(super) const CLASS: &str = "YogMirrors";

/// `yog:mirror/yog/entity` → `Entity`, `…/client/entity` → `ClientEntity`.
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
}

/// `BlockTrait`: each of `yog_ids::block_trait`'s bit, its place in the list.
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
}

/// The class's text.
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"
    )
}