1use serde::{Deserialize, Serialize};
11
12use crate::projects::{
13    parse_hashmap_string_value, parse_hashmap_string_value_bool, string_to_hashmap,
14    ProjectParseError, SectionHeader,
15};
16
17#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, Default)]
44pub struct State {
45    pub bank: u8,
47
48    pub pattern: u8,
50
51    pub arrangement: u8,
53
54    pub arrangement_mode: u8, pub part: u8,
59
60    pub track: u8,
62
63    pub track_othermode: u8, pub scene_a_mute: bool,
68
69    pub scene_b_mute: bool,
71
72    pub track_cue_mask: u8,
74
75    pub track_mute_mask: u8,
77
78    pub track_solo_mask: u8,
80
81    pub midi_track_mute_mask: u8,
83
84    pub midi_track_solo_mask: u8,
86
87    pub midi_mode: u8,
89}
90
91impl std::str::FromStr for State {
92    type Err = ProjectParseError;
93
94    fn from_str(s: &str) -> Result<Self, Self::Err> {
96        let hmap = string_to_hashmap(s, &SectionHeader::States)?;
97
98        Ok(Self {
99            bank: parse_hashmap_string_value::<u8>(&hmap, "bank", None)?,
100            pattern: parse_hashmap_string_value::<u8>(&hmap, "pattern", None)?,
101            arrangement: parse_hashmap_string_value::<u8>(&hmap, "arrangement", None)?,
102            arrangement_mode: parse_hashmap_string_value::<u8>(&hmap, "arrangement_mode", None)?,
103            part: parse_hashmap_string_value::<u8>(&hmap, "part", None)?,
104            track: parse_hashmap_string_value::<u8>(&hmap, "track", None)?,
105            track_othermode: parse_hashmap_string_value::<u8>(&hmap, "track_othermode", None)?,
106            scene_a_mute: parse_hashmap_string_value_bool(&hmap, "scene_a_mute", None)?,
107            scene_b_mute: parse_hashmap_string_value_bool(&hmap, "scene_b_mute", None)?,
108            track_cue_mask: parse_hashmap_string_value::<u8>(&hmap, "track_cue_mask", None)?,
109            track_mute_mask: parse_hashmap_string_value::<u8>(&hmap, "track_mute_mask", None)?,
110            track_solo_mask: parse_hashmap_string_value::<u8>(&hmap, "track_solo_mask", None)?,
111            midi_track_mute_mask: parse_hashmap_string_value::<u8>(
112                &hmap,
113                "midi_track_mute_mask",
114                None,
115            )?,
116            midi_track_solo_mask: parse_hashmap_string_value::<u8>(
117                &hmap,
118                "midi_track_solo_mask",
119                None,
120            )?,
121            midi_mode: parse_hashmap_string_value::<u8>(&hmap, "midi_mode", None)?,
122        })
123    }
124}
125
126impl std::fmt::Display for State {
127    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
128        let mut s = "".to_string();
129        s.push_str("[STATES]\r\n");
130        s.push_str(format!("BANK={}", self.bank).as_str());
131        s.push_str("\r\n");
132        s.push_str(format!("PATTERN={}", self.pattern).as_str());
133        s.push_str("\r\n");
134        s.push_str(format!("ARRANGEMENT={}", self.arrangement).as_str());
135        s.push_str("\r\n");
136        s.push_str(format!("ARRANGEMENT_MODE={}", self.arrangement_mode).as_str());
137        s.push_str("\r\n");
138        s.push_str(format!("PART={}", self.part).as_str());
139        s.push_str("\r\n");
140        s.push_str(format!("TRACK={}", self.track).as_str());
141        s.push_str("\r\n");
142        s.push_str(format!("TRACK_OTHERMODE={}", self.track_othermode).as_str());
143        s.push_str("\r\n");
144        s.push_str(format!("SCENE_A_MUTE={}", self.scene_a_mute as u8).as_str());
145        s.push_str("\r\n");
146        s.push_str(format!("SCENE_B_MUTE={}", self.scene_b_mute as u8).as_str());
147        s.push_str("\r\n");
148        s.push_str(format!("TRACK_CUE_MASK={}", self.track_cue_mask).as_str());
149        s.push_str("\r\n");
150        s.push_str(format!("TRACK_MUTE_MASK={}", self.track_mute_mask).as_str());
151        s.push_str("\r\n");
152        s.push_str(format!("TRACK_SOLO_MASK={}", self.track_solo_mask).as_str());
153        s.push_str("\r\n");
154        s.push_str(format!("MIDI_TRACK_MUTE_MASK={}", self.midi_track_mute_mask).as_str());
155        s.push_str("\r\n");
156        s.push_str(format!("MIDI_TRACK_SOLO_MASK={}", self.midi_track_solo_mask).as_str());
157        s.push_str("\r\n");
158        s.push_str(format!("MIDI_MODE={}", self.midi_mode).as_str());
159        s.push_str("\r\n[/STATES]");
160        write!(f, "{s:#}")
161    }
162}