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}