chart_file_parser/
chart.rs1use std::fmt::Display;
2
3use nom::{
4 bytes::complete::take_until,
5 character::complete::{multispace0, multispace1},
6 combinator::all_consuming,
7 multi::separated_list1,
8 IResult,
9};
10
11use crate::{events::Events, song::Song, sync_track::SyncTrack, track::Track};
12
13#[derive(Debug, PartialEq, Eq)]
14pub struct Chart<'a> {
15 song: Song<'a>,
16 synctrack: SyncTrack,
17 global_events: Events<'a>,
18 tracks: Vec<Track<'a>>,
19}
20
21impl<'a> Chart<'a> {
22 #[must_use]
23 pub(crate) fn new(
24 song: Song<'a>,
25 synctrack: SyncTrack,
26 global_events: Events<'a>,
27 tracks: Vec<Track<'a>>,
28 ) -> Self {
29 Self {
30 song,
31 synctrack,
32 global_events,
33 tracks,
34 }
35 }
36
37 pub fn multiply(&mut self, factor: u32) {
39 self.song.multiply(factor);
40 self.synctrack.multiply(factor);
41 self.global_events.multiply(factor);
42 for item in &mut self.tracks {
43 item.multiply(factor);
44 }
45 }
46
47 pub fn parse(input: &str) -> IResult<&str, Chart> {
54 let (input, _) = take_until("[")(input)?;
55 let (input, song) = Song::parse(input)?;
56 let (input, _) = multispace0(input)?;
57 let (input, synctrack) = SyncTrack::parse(input)?;
58 let (input, _) = multispace0(input)?;
59 let (input, global_events) = Events::parse(input)?;
60 let (input, _) = multispace0(input)?;
61 let (input, tracks) = separated_list1(multispace1, Track::parse)(input)?;
62 let (input, _) = all_consuming(multispace0)(input)?;
63 Ok((input, Chart::new(song, synctrack, global_events, tracks)))
64 }
65}
66
67impl<'a> Display for Chart<'a> {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 write!(
70 f,
71 "{}\n{}\n{}\n{}",
72 self.song,
73 self.synctrack,
74 self.global_events,
75 self.tracks.iter().map(Track::to_string).collect::<String>()
76 )
77 }
78}