proteus_lib/container/play_settings/
mod.rs1use log::{info, warn};
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5
6use crate::dsp::effects::AudioEffect;
7#[allow(deprecated)]
8#[deprecated(note = "Use DelayReverbSettings instead.")]
9pub use crate::dsp::effects::BasicReverbSettings;
10pub use crate::dsp::effects::{
11 CompressorSettings, ConvolutionReverbSettings, DelayReverbSettings, DistortionSettings,
12 EqPointSettings, HighEdgeFilterSettings, HighPassFilterSettings, LimiterSettings,
13 LowEdgeFilterSettings, LowPassFilterSettings, MultibandEqSettings,
14};
15
16pub mod legacy;
17pub mod v1;
18pub mod v2;
19pub mod v3;
20
21pub use legacy::{PlaySettingsLegacy, PlaySettingsLegacyFile, PlaySettingsTrackLegacy};
22pub use v1::{PlaySettingsV1, PlaySettingsV1File};
23pub use v2::{PlaySettingsV2, PlaySettingsV2File};
24pub use v3::{PlaySettingsV3, PlaySettingsV3File};
25
26pub type EffectSettings = AudioEffect;
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct SettingsTrack {
32 pub level: f32,
33 pub pan: f32,
34 pub ids: Vec<u32>,
35 pub name: String,
36 pub safe_name: String,
37 #[serde(default = "default_selections_count")]
38 pub selections_count: u32,
39 #[serde(default)]
40 pub shuffle_points: Vec<String>,
41}
42
43fn default_selections_count() -> u32 {
44 1
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
49#[serde(untagged)]
50pub enum PlaySettingsContainer<T> {
51 Nested { play_settings: T },
52 Flat(T),
53}
54
55impl<T> PlaySettingsContainer<T> {
56 pub fn inner(&self) -> &T {
58 match self {
59 PlaySettingsContainer::Nested { play_settings } => play_settings,
60 PlaySettingsContainer::Flat(inner) => inner,
61 }
62 }
63
64 pub fn inner_mut(&mut self) -> &mut T {
66 match self {
67 PlaySettingsContainer::Nested { play_settings } => play_settings,
68 PlaySettingsContainer::Flat(inner) => inner,
69 }
70 }
71}
72
73#[derive(Debug, Clone)]
75pub enum PlaySettingsFile {
76 Legacy(PlaySettingsLegacyFile),
77 V1(PlaySettingsV1File),
78 V2(PlaySettingsV2File),
79 V3(PlaySettingsV3File),
80 Unknown {
81 encoder_version: Option<String>,
82 raw: serde_json::Value,
83 },
84}
85
86impl PlaySettingsFile {
87 pub fn encoder_version(&self) -> Option<&str> {
89 match self {
90 PlaySettingsFile::Legacy(_) => None,
91 PlaySettingsFile::V1(_) => Some("1"),
92 PlaySettingsFile::V2(_) => Some("2"),
93 PlaySettingsFile::V3(_) => Some("3"),
94 PlaySettingsFile::Unknown {
95 encoder_version, ..
96 } => encoder_version.as_deref(),
97 }
98 }
99}
100
101impl<'de> Deserialize<'de> for PlaySettingsFile {
102 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
103 where
104 D: Deserializer<'de>,
105 {
106 let value = serde_json::Value::deserialize(deserializer)?;
107 let encoder_version = value.get("encoder_version").and_then(|raw| match raw {
108 serde_json::Value::String(version) => Some(version.clone()),
109 serde_json::Value::Number(number) => number
110 .as_f64()
111 .map(|val| {
112 if (val - 1.0).abs() < f64::EPSILON {
113 "1".to_string()
114 } else if (val - 2.0).abs() < f64::EPSILON {
115 "2".to_string()
116 } else if (val - 3.0).abs() < f64::EPSILON {
117 "3".to_string()
118 } else {
119 number.to_string()
120 }
121 })
122 .or_else(|| Some(number.to_string())),
123 _ => None,
124 });
125
126 info!("Encoder version: {:?}", encoder_version);
127
128 let parsed = match encoder_version.as_deref() {
129 None => serde_json::from_value::<PlaySettingsLegacyFile>(value.clone())
130 .map(PlaySettingsFile::Legacy),
131 Some("1") => serde_json::from_value::<PlaySettingsV1File>(value.clone())
132 .map(PlaySettingsFile::V1),
133 Some("2") => serde_json::from_value::<PlaySettingsV2File>(value.clone())
134 .map(PlaySettingsFile::V2),
135 Some("3") => serde_json::from_value::<PlaySettingsV3File>(value.clone())
136 .map(PlaySettingsFile::V3),
137 Some(version) => {
138 warn!("Unknown encoder version: {:?}", version);
139 return Ok(PlaySettingsFile::Unknown {
140 encoder_version,
141 raw: value,
142 });
143 }
144 };
145
146 parsed.or_else(|_| {
147 Ok(PlaySettingsFile::Unknown {
148 encoder_version,
149 raw: value,
150 })
151 })
152 }
153}
154
155impl Serialize for PlaySettingsFile {
156 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
157 where
158 S: Serializer,
159 {
160 fn with_version<T, S>(payload: &T, version: &str, serializer: S) -> Result<S::Ok, S::Error>
161 where
162 T: Serialize,
163 S: Serializer,
164 {
165 let mut value = serde_json::to_value(payload).map_err(serde::ser::Error::custom)?;
166 match value {
167 serde_json::Value::Object(ref mut map) => {
168 map.insert(
169 "encoder_version".to_string(),
170 serde_json::Value::String(version.to_string()),
171 );
172 }
173 other => {
174 let mut map = serde_json::Map::new();
175 map.insert(
176 "encoder_version".to_string(),
177 serde_json::Value::String(version.to_string()),
178 );
179 map.insert("play_settings".to_string(), other);
180 value = serde_json::Value::Object(map);
181 }
182 }
183 value.serialize(serializer)
184 }
185
186 match self {
187 PlaySettingsFile::Legacy(file) => file.serialize(serializer),
188 PlaySettingsFile::V1(file) => with_version(file, "1", serializer),
189 PlaySettingsFile::V2(file) => with_version(file, "2", serializer),
190 PlaySettingsFile::V3(file) => with_version(file, "3", serializer),
191 PlaySettingsFile::Unknown { raw, .. } => raw.serialize(serializer),
192 }
193 }
194}