quaver-rs 0.1.0

A Rust library for parsing and analyzing Quaver rhythm game maps
Documentation

/// HitObjects section of the .qua
#[derive(Debug, Clone, PartialEq)]
pub struct HitObjectInfo {
    /// The time in milliseconds when the HitObject is supposed to be hit.
    pub start_time: f32,
    
    /// The lane the HitObject falls in
    pub lane: i32,
    
    /// The endtime of the HitObject (if greater than 0, it's considered a hold note.)
    pub end_time: f32,
    
    /// Bitwise combination of hit sounds for this object
    pub hit_sound: HitSounds,
    
    /// Key sounds to play when this object is hit.
    pub key_sounds: Vec<KeySoundInfo>,
    
    /// The layer in the editor that the object belongs to.
    pub editor_layer: i32,
    
    /// ID of the timing group this note belongs to. Leave empty for default timing group.
    pub timing_group: String,
    
    /// If the object is allowed to be edited in lua scripts
    pub is_editable_in_lua_script: bool,
}

impl HitObjectInfo {
    /// If the object is a long note. (EndTime > 0)
    pub fn is_long_note(&self) -> bool {
        self.end_time > 0.0
    }
    
    /// Gets the timing point this object is in range of.
    pub fn get_timing_point<'a>(&self, timing_points: &'a [TimingPointInfo]) -> Option<&'a TimingPointInfo> {
        timing_points.iter()
            .find(|tp| tp.start_time <= self.start_time)
            .or_else(|| timing_points.first())
    }
    
    /// Set start time (with editability check)
    pub fn set_start_time(&mut self, time: f32) -> Result<(), String> {
        self.check_editable()?;
        self.start_time = time;
        Ok(())
    }
    
    /// Set end time (with editability check)
    pub fn set_end_time(&mut self, time: f32) -> Result<(), String> {
        self.check_editable()?;
        self.end_time = time;
        Ok(())
    }
    
    /// Set lane (with editability check)
    pub fn set_lane(&mut self, lane: i32) -> Result<(), String> {
        self.check_editable()?;
        self.lane = lane;
        Ok(())
    }
    
    /// Set hit sounds (with editability check)
    pub fn set_hit_sounds(&mut self, hit_sounds: HitSounds) -> Result<(), String> {
        self.check_editable()?;
        self.hit_sound = hit_sounds;
        Ok(())
    }
    
    /// Check if object is editable in lua scripts
    fn check_editable(&self) -> Result<(), String> {
        if !self.is_editable_in_lua_script {
            Err("Value is not allowed to be edited in lua scripts.".to_string())
        } else {
            Ok(())
        }
    }
}

/// Hit sounds enum (bitwise combination)
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum HitSounds {
    None = 0,
    Normal = 1,
    Whistle = 2,
    Finish = 4,
    Clap = 8,
}

/// Key sound information
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct KeySoundInfo {
    pub sample_set: String,
    pub addition_set: String,
    pub custom_index: i32,
    pub sample_volume: i32,
    pub filename: String,
}

/// Timing point information
#[derive(Debug, Clone, PartialEq)]
pub struct TimingPointInfo {
    pub start_time: f32,
    pub bpm: f32,
    pub signature: i32,
}

/// Default scroll group ID constant
pub const DEFAULT_SCROLL_GROUP_ID: &str = "default";