character-traits-warrior-capability 0.1.0

A Rust crate for modeling and simulating a broad spectrum of warrior capabilities, aimed at enhancing intricate game mechanics and strategic simulations.
Documentation
// ---------------- [ File: character-traits-warrior-capability/src/capability_variant.rs ]
crate::ix!();

/// Implemented **once** for every *leaf‑level* capability enum
/// (e.g. `WarriorApproachCapability`, `WarriorTechAdaptationCapability`, …).
///
/// The enum itself provides:
/// * its **intrinsic ratings vector** (`intrinsic_ratings`);
/// * a **static slice of all variants** (`all_variants`) for enumeration.
pub trait CapabilityVariant: Clone + Eq + std::hash::Hash + Sized {
    /// Return the *dense 115‑element* intrinsic‑dimension ratings that
    /// characterize *this* capability variant.
    fn intrinsic_ratings(&self) -> &WarriorCapabilityIntrinsicDimensionRatings;

    /// Exhaustive slice of every variant value—used for enumeration
    /// when computing probabilities.
    fn all_variants() -> &'static [Self];
}

/// Blanket‑implement `CapabilityVariant` for every leaf enum that
///   * derives **`EnumIter`** (from `strum_macros`) and  
///   * provides `intrinsic_dimension_ratings()`.
///
/// The `OnceLock` caches avoid recomputing vectors on every call, while
/// `EnumIter` eliminates any need for unstable `variant_count` or unsafe
/// transmutes.
#[macro_export]
macro_rules! impl_capability_variant {
    ( $($ty:ty),+ $(,)? ) => {
        $(
            impl CapabilityVariant for $ty {
                fn intrinsic_ratings(&self) -> &WarriorCapabilityIntrinsicDimensionRatings {
                    use std::sync::OnceLock;
                    use strum::IntoEnumIterator;

                    static CACHE: OnceLock<
                        Vec<WarriorCapabilityIntrinsicDimensionRatings>
                    > = OnceLock::new();

                    let ratings = CACHE.get_or_init(|| {
                        <$ty as IntoEnumIterator>::iter()
                            .map(|v| v.intrinsic_dimension_ratings())
                            .collect::<Vec<_>>()
                    });

                    // safe because `EnumIter` guarantees contiguous indices
                    &ratings[*self as usize]
                }

                fn all_variants() -> &'static [Self] {
                    use std::sync::OnceLock;
                    use strum::IntoEnumIterator;

                    static VARS: OnceLock<Vec<$ty>> = OnceLock::new();
                    VARS.get_or_init(|| <$ty as IntoEnumIterator>::iter().collect())
                }
            }
        )+
    };
}

impl_capability_variant!{
    WarriorApproachCapability,
    WarriorBraveryCapability,
    WarriorConflictMitigationCapability,
    WarriorCyberDefenseCapability,
    WarriorDefensiveMagicCapability,
    WarriorEmbodimentCapability,
    WarriorExplorationCapability,
    WarriorIllusionaryMagicCapability,
    WarriorLeadershipCapability,
    WarriorMetaCapability,
    WarriorOffensiveMagicCapability,
    WarriorPhysicalCapability,
    WarriorProtectiveCapability,
    WarriorResilienceCapability,
    WarriorResponsivenessCapability,
    WarriorStrategicCapability,
    WarriorTechAdaptationCapability,
    WarriorThreatAdaptationCapability,
}