1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use std::str::FromStr;

pub use self::decode::{Events, EventsState, ParseEventsError};

pub(crate) mod decode; // pub(crate) for intradoc-links

/// A break section during a [`Beatmap`].
///
/// [`Beatmap`]: crate::beatmap::Beatmap
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct BreakPeriod {
    pub start_time: f64,
    pub end_time: f64,
}

impl BreakPeriod {
    /// The minimum duration required for a break to have any effect.
    pub const MIN_BREAK_DURATION: f64 = 650.0;

    /// The duration of the break.
    pub fn duration(&self) -> f64 {
        self.end_time - self.start_time
    }

    /// Whether the break has any effect.
    pub fn has_effect(&self) -> bool {
        self.duration() >= Self::MIN_BREAK_DURATION
    }
}

/// The type of an event.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum EventType {
    Background,
    Video,
    Break,
    Color,
    Sprite,
    Sample,
    Animation,
}

impl FromStr for EventType {
    type Err = ParseEventTypeError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "0" | "Background" => Ok(Self::Background),
            "1" | "Video" => Ok(Self::Video),
            "2" | "Break" => Ok(Self::Break),
            "3" | "Colour" => Ok(Self::Color),
            "4" | "Sprite" => Ok(Self::Sprite),
            "5" | "Sample" => Ok(Self::Sample),
            "6" | "Animation" => Ok(Self::Animation),
            _ => Err(ParseEventTypeError),
        }
    }
}

thiserror! {
    #[error("invalid event type")]
    /// Error when failing to parse an [`EventType`].
    #[derive(Debug)]
    pub struct ParseEventTypeError;
}