quaver-rs 0.1.0

A Rust library for parsing and analyzing Quaver rhythm game maps
Documentation
use std::collections::HashMap;
use crate::hit_object_info::HitObjectInfo;
use crate::enums::GameMode;
use super::{MapMetadata, TimingPointInfo, TimingGroup, EditorLayerInfo, BookmarkInfo, CustomAudioSampleInfo, SoundEffectInfo};

// GameMode is now imported from crate::enums::GameMode

/// Main Qua map structure
#[derive(Debug, Clone)]
pub struct Qua {
    /// Map metadata
    pub metadata: MapMetadata,
    
    /// List of timing points
    pub timing_points: Vec<TimingPointInfo>,
    
    /// List of hit objects
    pub hit_objects: Vec<HitObjectInfo>,
    
    /// List of editor layers
    pub editor_layers: Vec<EditorLayerInfo>,
    
    /// List of bookmarks
    pub bookmarks: Vec<BookmarkInfo>,
    
    /// List of custom audio samples
    pub custom_audio_samples: Vec<CustomAudioSampleInfo>,
    
    /// List of sound effects
    pub sound_effects: Vec<SoundEffectInfo>,
    
    /// Timing groups
    pub timing_groups: HashMap<String, TimingGroup>,
}

impl Qua {
    /// Default scroll group ID constant
    pub const DEFAULT_SCROLL_GROUP_ID: &'static str = "default";
    
    /// Create a new empty Qua map
    pub fn new() -> Self {
        Self {
            metadata: MapMetadata::default(),
            timing_points: Vec::new(),
            hit_objects: Vec::new(),
            editor_layers: Vec::new(),
            bookmarks: Vec::new(),
            custom_audio_samples: Vec::new(),
            sound_effects: Vec::new(),
            timing_groups: HashMap::new(),
        }
    }
    
    /// Get the game mode as a number
    pub fn mode(&self) -> GameMode {
        self.metadata.mode
    }
    
    /// Get the key count for the current mode
    pub fn get_key_count(&self, include_scratch: bool) -> i32 {
        self.metadata.mode.to_key_count(include_scratch)
    }
    
    /// Check if the map has a scratch key
    pub fn has_scratch_key(&self) -> bool {
        self.metadata.has_scratch_key
    }
    
    /// Get the length of the map in milliseconds
    pub fn length(&self) -> f32 {
        if self.hit_objects.is_empty() {
            return 0.0;
        }
        
        self.hit_objects
            .iter()
            .map(|obj| obj.end_time.max(obj.start_time) as f32)
            .fold(0.0, f32::max)
    }
    
    /// Get the mode as GameMode enum
    pub fn game_mode(&self) -> GameMode {
        self.metadata.mode
    }
}

impl Default for Qua {
    fn default() -> Self {
        Self::new()
    }
}

// Re-export parser methods
impl Qua {
    /// Parse a .qua file from a file path
    pub fn from_file(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
        crate::qua::parser::parse_from_file(path)
    }
    
    /// Parse a .qua file from a string
    pub fn from_str(content: &str) -> Result<Self, Box<dyn std::error::Error>> {
        crate::qua::parser::parse_from_str(content)
    }
}