bms_rs/bms/model/
section_len.rs

1//! This module introduces struct [`SectionLenObjects`], which manages events of section length change.
2
3use std::{
4    collections::{BTreeMap, btree_map::Entry},
5    num::NonZeroU64,
6};
7
8use crate::{
9    bms::{error::Result, prelude::*},
10    parse::prompt::TrackDuplication,
11};
12
13#[derive(Debug, Default, Clone, PartialEq, Eq)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15/// This aggregate manages events of section length change.
16pub struct SectionLenObjects {
17    /// Section length change events, indexed by track. `#SECLEN`
18    pub section_len_changes: BTreeMap<Track, SectionLenChangeObj>,
19}
20
21impl SectionLenObjects {
22    /// Gets the time of the last section length change.
23    #[must_use]
24    pub fn last_obj_time(&self) -> Option<ObjTime> {
25        self.section_len_changes.last_key_value().map(|(&time, _)| {
26            ObjTime::new(
27                time.0,
28                0,
29                NonZeroU64::new(4).expect("4 should be a valid NonZeroU64"),
30            )
31        })
32    }
33}
34
35impl SectionLenObjects {
36    /// Adds a new section length change object to the notes.
37    pub fn push_section_len_change(
38        &mut self,
39        section_len_change: SectionLenChangeObj,
40        prompt_handler: &impl Prompter,
41    ) -> Result<()> {
42        match self.section_len_changes.entry(section_len_change.track) {
43            Entry::Vacant(entry) => {
44                entry.insert(section_len_change);
45                Ok(())
46            }
47            Entry::Occupied(mut entry) => {
48                let existing = entry.get();
49
50                prompt_handler
51                    .handle_track_duplication(TrackDuplication::SectionLenChangeEvent {
52                        track: section_len_change.track,
53                        older: existing,
54                        newer: &section_len_change,
55                    })
56                    .apply_track(
57                        entry.get_mut(),
58                        section_len_change.clone(),
59                        section_len_change.track,
60                        Channel::SectionLen,
61                    )
62            }
63        }
64    }
65}