quaver-rs 0.1.0

A Rust library for parsing and analyzing Quaver rhythm game maps
Documentation
use crate::rulesets::structs::{Hand, FingerState};
use crate::enums::{GameMode, ModIdentifier};

/// Helper functions for difficulty calculation

/// Assumes that the assigned hand will be the one to press that key
pub fn lane_to_hand(lane: i32, key_count: i32) -> Result<Hand, String> {
    if lane < 1 || lane > key_count {
        return Err(format!("Lane must be between 1 and keyCount, got {}", lane));
    }

    let half = key_count / 2;

    if key_count % 2 == 0 {
        if lane <= half {
            Ok(Hand::Left)
        } else {
            Ok(Hand::Right)
        }
    } else {
        if lane <= half {
            Ok(Hand::Left)
        } else if lane == half + 1 {
            Ok(Hand::Ambiguous)
        } else {
            Ok(Hand::Right)
        }
    }
}

/// Assumes that the assigned finger will be the one to press that key.
pub fn lane_to_finger(lane: i32, key_count: i32) -> Result<FingerState, String> {
    if lane < 1 || lane > key_count {
        return Err(format!("Lane must be between 1 and keyCount, got {}", lane));
    }

    let half = key_count / 2;

    if key_count <= 9 {
        // even key count
        if key_count % 2 == 0 {
            if lane <= half {
                Ok(FingerState::from_bits(1 << (half - lane)).unwrap_or(FingerState::NONE))
            } else {
                Ok(FingerState::from_bits(1 << (lane - (half + 1))).unwrap_or(FingerState::NONE))
            }
        } else {
            // odd key count
            if lane <= half {
                Ok(FingerState::from_bits(1 << (half - lane)).unwrap_or(FingerState::NONE))
            } else if lane == half + 1 {
                Ok(FingerState::THUMB)
            } else {
                Ok(FingerState::from_bits(1 << (lane - (half + 2))).unwrap_or(FingerState::NONE))
            }
        }
    } else if key_count == 10 {
        if lane <= half - 1 {
            Ok(FingerState::from_bits(1 << (half - 1 - lane)).unwrap_or(FingerState::NONE))
        } else if lane == half || lane == half + 1 {
            Ok(FingerState::THUMB)
        } else {
            Ok(FingerState::from_bits(1 << (lane - (half + 2))).unwrap_or(FingerState::NONE))
        }
    } else {
        Err(format!("Key count must be between 1 and 10, got {}", key_count))
    }
}

/// Get rate from mods
pub fn get_rate_from_mods(mods: ModIdentifier) -> f32 {
    mods.get_rate_from_mods()
}

/// Convert mode to key count
pub fn mode_to_key_count(mode: GameMode) -> i32 {
    mode.to_key_count(false) // Default to no scratch
}

/// Get key count from map (placeholder implementation)
pub fn get_key_count(_has_scratch_key: bool) -> i32 {
    // TODO: Implement proper key count calculation
    4
}