chart_file_parser/
track.rs1use std::fmt::Display;
2
3use nom::{
4 character::complete::{alpha1, multispace1},
5 combinator::map,
6 multi::separated_list1,
7 sequence::tuple,
8 IResult,
9};
10
11use crate::{
12 components::{curlied, spaced, squared},
13 track_event::TrackEvent,
14};
15
16#[derive(Debug, PartialEq, Eq)]
17pub struct Track<'a> {
18 name: &'a str,
19 events: Vec<TrackEvent<'a>>,
20}
21
22impl<'a> Track<'a> {
23 #[must_use]
24 pub(crate) fn new(name: &'a str, events: Vec<TrackEvent<'a>>) -> Self {
25 Self { name, events }
26 }
27
28 pub(crate) fn multiply(&mut self, factor: u32) {
29 for item in &mut self.events {
30 item.multiply(factor);
31 }
32 }
33
34 #[inline]
35 pub(crate) fn parse(input: &str) -> IResult<&str, Track> {
36 map(
37 tuple((
38 spaced(squared(alpha1)),
39 curlied(spaced(separated_list1(multispace1, TrackEvent::parse))),
40 )),
41 |(name, events)| Track::new(name, events),
42 )(input)
43 }
44}
45
46impl<'a> Display for Track<'a> {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 write!(
49 f,
50 "[{}]\n{{\n{}}}\n",
51 self.name,
52 self.events
53 .iter()
54 .map(TrackEvent::to_string)
55 .collect::<String>()
56 )
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 #![allow(clippy::unwrap_used)]
63 use super::*;
64
65 #[test]
66 fn test_track() {
67 Track::parse(include_str!("test_data/test_track.txt")).unwrap();
68 }
69}