ot_tools_io/projects/slots/
deserialize.rs1use crate::generics::{PlaybackSlots, RecordingBufferSlots, Slots};
7use crate::projects::SlotAttributes;
8use crate::settings::{LoopMode, SlotType, TimeStretchMode, TrigQuantizationMode};
9use serde::{
10 de::{self, MapAccess, Visitor},
11 Deserialize, Deserializer,
12};
13use std::fmt;
14use std::path::PathBuf;
15
16impl<'de> Deserialize<'de> for SlotAttributes {
20 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
21 where
22 D: Deserializer<'de>,
23 {
24 enum Field {
25 SlotType,
26 SlotId,
27 Path,
28 Timestretch,
29 Loop,
30 Quant,
31 Gain,
32 Bpm,
33 }
34
35 const FIELDS: &[&str] = &[
37 "slot_type",
38 "slot_id",
39 "path",
40 "timestrech_mode",
41 "loop_mode",
42 "trig_quantization_mode",
43 "gain",
44 "bpm",
45 ];
46
47 impl<'de> Deserialize<'de> for Field {
48 fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
49 where
50 D: Deserializer<'de>,
51 {
52 struct FieldVisitor;
53
54 impl Visitor<'_> for FieldVisitor {
55 type Value = Field;
56
57 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
58 formatter.write_str(
59 FIELDS
60 .iter()
61 .map(|x| format!["`{x}`"])
62 .collect::<Vec<_>>()
63 .join(" or ")
64 .as_str(),
65 )
66 }
67
68 fn visit_str<E>(self, value: &str) -> Result<Field, E>
69 where
70 E: de::Error,
71 {
72 match value {
73 "slot_type" => Ok(Field::SlotType),
74 "slot_id" => Ok(Field::SlotId),
75 "path" => Ok(Field::Path),
76 "timestrech_mode" => Ok(Field::Timestretch),
77 "loop_mode" => Ok(Field::Loop),
78 "trig_quantization_mode" => Ok(Field::Quant),
79 "gain" => Ok(Field::Gain),
80 "bpm" => Ok(Field::Bpm),
81 _ => Err(de::Error::unknown_field(value, FIELDS)),
82 }
83 }
84 }
85
86 deserializer.deserialize_identifier(FieldVisitor)
87 }
88 }
89
90 struct SlotAttributesVisitor;
91
92 impl<'de> Visitor<'de> for SlotAttributesVisitor {
93 type Value = SlotAttributes;
94
95 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
96 formatter.write_str("struct SlotAttributes")
97 }
98
99 fn visit_map<V>(self, mut map: V) -> Result<SlotAttributes, V::Error>
100 where
101 V: MapAccess<'de>,
102 {
103 let mut slot_type = None;
104 let mut slot_id = None;
105 let mut path = None;
106 let mut timestretch_mode = None;
107 let mut loop_mode = None;
108 let mut trig_quantization_mode = None;
109 let mut gain = None;
110 let mut bpm = None;
111
112 while let Some(key) = map.next_key()? {
113 match key {
114 Field::SlotType => {
115 if slot_type.is_some() {
116 return Err(de::Error::duplicate_field("slot_type"));
117 }
118 slot_type = Some(map.next_value::<SlotType>()?);
119 }
120 Field::SlotId => {
121 if slot_id.is_some() {
122 return Err(de::Error::duplicate_field("slot_id"));
123 }
124 slot_id = Some(map.next_value::<u8>()?);
125 }
126 Field::Path => {
127 if path.is_some() {
128 return Err(de::Error::duplicate_field("path"));
129 }
130 path = Some(map.next_value::<PathBuf>()?);
131 }
132 Field::Timestretch => {
133 if timestretch_mode.is_some() {
134 return Err(de::Error::duplicate_field("timestretch_mode"));
135 }
136 timestretch_mode = Some(map.next_value::<TimeStretchMode>()?);
137 }
138 Field::Loop => {
139 if loop_mode.is_some() {
140 return Err(de::Error::duplicate_field("loop_mode"));
141 }
142 loop_mode = Some(map.next_value::<LoopMode>()?);
143 }
144 Field::Quant => {
145 if trig_quantization_mode.is_some() {
146 return Err(de::Error::duplicate_field("trig_quantization_mode"));
147 }
148 trig_quantization_mode =
149 Some(map.next_value::<TrigQuantizationMode>()?);
150 }
151 Field::Gain => {
152 if gain.is_some() {
153 return Err(de::Error::duplicate_field("gain"));
154 }
155 gain = Some(map.next_value::<u8>()?);
156 }
157 Field::Bpm => {
158 if bpm.is_some() {
159 return Err(de::Error::duplicate_field("bpm"));
160 }
161 bpm = Some(map.next_value::<u16>()?);
162 }
163 }
164 }
165
166 let slot = SlotAttributes {
167 slot_type: slot_type.ok_or_else(|| de::Error::missing_field("slot_type"))?,
168 slot_id: slot_id.ok_or_else(|| de::Error::missing_field("slot_type"))?,
169 path, timestrech_mode: timestretch_mode
171 .ok_or_else(|| de::Error::missing_field("trimstretch_mode"))?,
172 loop_mode: loop_mode.ok_or_else(|| de::Error::missing_field("loop_mode"))?,
173 trig_quantization_mode: trig_quantization_mode
174 .ok_or_else(|| de::Error::missing_field("trig_quantization_mode"))?,
175 gain: gain.ok_or_else(|| de::Error::missing_field("gain"))?,
176 bpm: bpm.ok_or_else(|| de::Error::missing_field("bpm"))?,
177 };
178
179 Ok(slot)
180 }
181 }
182
183 deserializer.deserialize_struct("SampleSlot", FIELDS, SlotAttributesVisitor)
184 }
185}
186
187impl<'de> Deserialize<'de> for Slots<Option<SlotAttributes>> {
191 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
192 where
193 D: Deserializer<'de>,
194 {
195 enum Field {
196 Static,
197 Flex,
198 Recording,
199 }
200
201 impl<'de> Deserialize<'de> for Field {
202 fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
203 where
204 D: Deserializer<'de>,
205 {
206 struct FieldVisitor;
207
208 impl Visitor<'_> for FieldVisitor {
209 type Value = Field;
210
211 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
212 formatter.write_str("`static_slots` or `flex_slots` or `recording_buffers`")
213 }
214
215 fn visit_str<E>(self, value: &str) -> Result<Field, E>
216 where
217 E: de::Error,
218 {
219 match value {
220 "static_slots" => Ok(Field::Static),
221 "flex_slots" => Ok(Field::Flex),
222 "recording_buffers" => Ok(Field::Recording),
223 _ => Err(de::Error::unknown_field(value, FIELDS)),
224 }
225 }
226 }
227
228 deserializer.deserialize_identifier(FieldVisitor)
229 }
230 }
231
232 struct SampleSlotsVisitor;
233
234 impl<'de> Visitor<'de> for SampleSlotsVisitor {
235 type Value = Slots<Option<SlotAttributes>>;
236
237 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
238 formatter.write_str("struct Slots<Option<SlotAttributes>>")
239 }
240
241 fn visit_unit<E>(self) -> Result<Slots<Option<SlotAttributes>>, E> {
242 Ok(Slots::<Option<SlotAttributes>>::default())
243 }
244
245 fn visit_map<V>(self, mut map: V) -> Result<Slots<Option<SlotAttributes>>, V::Error>
246 where
247 V: MapAccess<'de>,
248 {
249 let mut s_slots = None;
250 let mut f_slots = None;
251 let mut r_slots = None;
252
253 while let Some(key) = map.next_key()? {
254 match key {
255 Field::Static => {
256 if s_slots.is_some() {
257 return Err(de::Error::duplicate_field("static_slots"));
258 }
259 s_slots =
260 Some(map.next_value::<PlaybackSlots<Option<SlotAttributes>>>()?);
261 }
262 Field::Flex => {
263 if f_slots.is_some() {
264 return Err(de::Error::duplicate_field("flex_slots"));
265 }
266 f_slots =
267 Some(map.next_value::<PlaybackSlots<Option<SlotAttributes>>>()?);
268 }
269 Field::Recording => {
270 if r_slots.is_some() {
271 return Err(de::Error::duplicate_field("recording_buffers"));
272 }
273 r_slots = Some(
274 map.next_value::<RecordingBufferSlots<Option<SlotAttributes>>>()?,
275 );
276 }
277 }
278 }
279
280 let static_slots =
281 s_slots.ok_or_else(|| de::Error::missing_field("static_slots"))?;
282
283 let flex_slots = f_slots.ok_or_else(|| de::Error::missing_field("flex_slots"))?;
284
285 let recording_buffers =
286 r_slots.ok_or_else(|| de::Error::missing_field("recording_buffers"))?;
287
288 Ok(Slots::new(flex_slots, recording_buffers, static_slots))
289 }
290 }
291
292 const FIELDS: &[&str] = &["static_slots", "flex_slots", "recording_buffers"];
293 deserializer.deserialize_struct("SampleSlots", FIELDS, SampleSlotsVisitor)
294 }
295}