1use crate::projects::{
11 parse_hashmap_string_value, parse_hashmap_string_value_bool, string_to_hashmap,
12 ProjectParseError, SectionHeader,
13};
14use ot_tools_io_derive::{AsMutDerive, AsRefDerive};
15use serde::{Deserialize, Serialize};
16
17#[derive(
44 Copy,
45 Clone,
46 Debug,
47 Default, Eq,
49 Hash,
50 Ord,
51 PartialEq,
52 PartialOrd,
53 Serialize,
54 Deserialize,
55 AsMutDerive,
56 AsRefDerive,
57)]
58pub struct State {
59 pub bank: u8,
61
62 pub pattern: u8,
64
65 pub arrangement: u8,
67
68 pub arrangement_mode: u8, pub part: u8,
73
74 pub track: u8,
76
77 pub track_othermode: u8, pub scene_a_mute: bool,
82
83 pub scene_b_mute: bool,
85
86 pub track_cue_mask: u8,
88
89 pub track_mute_mask: u8,
91
92 pub track_solo_mask: u8,
94
95 pub midi_track_mute_mask: u8,
97
98 pub midi_track_solo_mask: u8,
100
101 pub midi_mode: u8,
103}
104
105impl std::str::FromStr for State {
106 type Err = ProjectParseError;
107
108 fn from_str(s: &str) -> Result<Self, Self::Err> {
110 let hmap = string_to_hashmap(s, &SectionHeader::States)?;
111
112 Ok(Self {
113 bank: parse_hashmap_string_value::<u8>(&hmap, "bank", None)?,
114 pattern: parse_hashmap_string_value::<u8>(&hmap, "pattern", None)?,
115 arrangement: parse_hashmap_string_value::<u8>(&hmap, "arrangement", None)?,
116 arrangement_mode: parse_hashmap_string_value::<u8>(&hmap, "arrangement_mode", None)?,
117 part: parse_hashmap_string_value::<u8>(&hmap, "part", None)?,
118 track: parse_hashmap_string_value::<u8>(&hmap, "track", None)?,
119 track_othermode: parse_hashmap_string_value::<u8>(&hmap, "track_othermode", None)?,
120 scene_a_mute: parse_hashmap_string_value_bool(&hmap, "scene_a_mute", None)?,
121 scene_b_mute: parse_hashmap_string_value_bool(&hmap, "scene_b_mute", None)?,
122 track_cue_mask: parse_hashmap_string_value::<u8>(&hmap, "track_cue_mask", None)?,
123 track_mute_mask: parse_hashmap_string_value::<u8>(&hmap, "track_mute_mask", None)?,
124 track_solo_mask: parse_hashmap_string_value::<u8>(&hmap, "track_solo_mask", None)?,
125 midi_track_mute_mask: parse_hashmap_string_value::<u8>(
126 &hmap,
127 "midi_track_mute_mask",
128 None,
129 )?,
130 midi_track_solo_mask: parse_hashmap_string_value::<u8>(
131 &hmap,
132 "midi_track_solo_mask",
133 None,
134 )?,
135 midi_mode: parse_hashmap_string_value::<u8>(&hmap, "midi_mode", None)?,
136 })
137 }
138}
139
140impl std::fmt::Display for State {
141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
142 let mut s = "".to_string();
143 s.push_str("[STATES]\r\n");
144 s.push_str(format!("BANK={}", self.bank).as_str());
145 s.push_str("\r\n");
146 s.push_str(format!("PATTERN={}", self.pattern).as_str());
147 s.push_str("\r\n");
148 s.push_str(format!("ARRANGEMENT={}", self.arrangement).as_str());
149 s.push_str("\r\n");
150 s.push_str(format!("ARRANGEMENT_MODE={}", self.arrangement_mode).as_str());
151 s.push_str("\r\n");
152 s.push_str(format!("PART={}", self.part).as_str());
153 s.push_str("\r\n");
154 s.push_str(format!("TRACK={}", self.track).as_str());
155 s.push_str("\r\n");
156 s.push_str(format!("TRACK_OTHERMODE={}", self.track_othermode).as_str());
157 s.push_str("\r\n");
158 s.push_str(format!("SCENE_A_MUTE={}", self.scene_a_mute as u8).as_str());
159 s.push_str("\r\n");
160 s.push_str(format!("SCENE_B_MUTE={}", self.scene_b_mute as u8).as_str());
161 s.push_str("\r\n");
162 s.push_str(format!("TRACK_CUE_MASK={}", self.track_cue_mask).as_str());
163 s.push_str("\r\n");
164 s.push_str(format!("TRACK_MUTE_MASK={}", self.track_mute_mask).as_str());
165 s.push_str("\r\n");
166 s.push_str(format!("TRACK_SOLO_MASK={}", self.track_solo_mask).as_str());
167 s.push_str("\r\n");
168 s.push_str(format!("MIDI_TRACK_MUTE_MASK={}", self.midi_track_mute_mask).as_str());
169 s.push_str("\r\n");
170 s.push_str(format!("MIDI_TRACK_SOLO_MASK={}", self.midi_track_solo_mask).as_str());
171 s.push_str("\r\n");
172 s.push_str(format!("MIDI_MODE={}", self.midi_mode).as_str());
173 s.push_str("\r\n[/STATES]");
174 write!(f, "{s:#}")
175 }
176}