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 HighPassFilterSettings, LimiterSettings, LowPassFilterSettings,
13};
14
15pub mod legacy;
16pub mod v1;
17pub mod v2;
18
19pub use legacy::{PlaySettingsLegacy, PlaySettingsLegacyFile, PlaySettingsTrackLegacy};
20pub use v1::{PlaySettingsV1, PlaySettingsV1File};
21pub use v2::{PlaySettingsV2, PlaySettingsV2File};
22
23pub type EffectSettings = AudioEffect;
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct SettingsTrack {
29 pub level: f32,
30 pub pan: f32,
31 pub ids: Vec<u32>,
32 pub name: String,
33 pub safe_name: String,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
38#[serde(untagged)]
39pub enum PlaySettingsContainer<T> {
40 Nested { play_settings: T },
41 Flat(T),
42}
43
44impl<T> PlaySettingsContainer<T> {
45 pub fn inner(&self) -> &T {
47 match self {
48 PlaySettingsContainer::Nested { play_settings } => play_settings,
49 PlaySettingsContainer::Flat(inner) => inner,
50 }
51 }
52}
53
54#[derive(Debug, Clone)]
56pub enum PlaySettingsFile {
57 Legacy(PlaySettingsLegacyFile),
58 V1(PlaySettingsV1File),
59 V2(PlaySettingsV2File),
60 Unknown {
61 encoder_version: Option<String>,
62 raw: serde_json::Value,
63 },
64}
65
66impl PlaySettingsFile {
67 pub fn encoder_version(&self) -> Option<&str> {
69 match self {
70 PlaySettingsFile::Legacy(_) => None,
71 PlaySettingsFile::V1(_) => Some("1"),
72 PlaySettingsFile::V2(_) => Some("2"),
73 PlaySettingsFile::Unknown {
74 encoder_version, ..
75 } => encoder_version.as_deref(),
76 }
77 }
78}
79
80impl<'de> Deserialize<'de> for PlaySettingsFile {
81 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
82 where
83 D: Deserializer<'de>,
84 {
85 let value = serde_json::Value::deserialize(deserializer)?;
86 let encoder_version = value.get("encoder_version").and_then(|raw| match raw {
87 serde_json::Value::String(version) => Some(version.clone()),
88 serde_json::Value::Number(number) => number
89 .as_f64()
90 .map(|val| {
91 if (val - 1.0).abs() < f64::EPSILON {
92 "1".to_string()
93 } else if (val - 2.0).abs() < f64::EPSILON {
94 "2".to_string()
95 } else {
96 number.to_string()
97 }
98 })
99 .or_else(|| Some(number.to_string())),
100 _ => None,
101 });
102
103 info!("Encoder version: {:?}", encoder_version);
104
105 let parsed = match encoder_version.as_deref() {
106 None => serde_json::from_value::<PlaySettingsLegacyFile>(value.clone())
107 .map(PlaySettingsFile::Legacy),
108 Some("1") => serde_json::from_value::<PlaySettingsV1File>(value.clone())
109 .map(PlaySettingsFile::V1),
110 Some("2") => serde_json::from_value::<PlaySettingsV2File>(value.clone())
111 .map(PlaySettingsFile::V2),
112 Some(version) => {
113 warn!("Unknown encoder version: {:?}", version);
114 return Ok(PlaySettingsFile::Unknown {
115 encoder_version,
116 raw: value,
117 });
118 }
119 };
120
121 parsed.or_else(|_| {
122 Ok(PlaySettingsFile::Unknown {
123 encoder_version,
124 raw: value,
125 })
126 })
127 }
128}
129
130impl Serialize for PlaySettingsFile {
131 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
132 where
133 S: Serializer,
134 {
135 fn with_version<T, S>(payload: &T, version: &str, serializer: S) -> Result<S::Ok, S::Error>
136 where
137 T: Serialize,
138 S: Serializer,
139 {
140 let mut value = serde_json::to_value(payload).map_err(serde::ser::Error::custom)?;
141 match value {
142 serde_json::Value::Object(ref mut map) => {
143 map.insert(
144 "encoder_version".to_string(),
145 serde_json::Value::String(version.to_string()),
146 );
147 }
148 other => {
149 let mut map = serde_json::Map::new();
150 map.insert(
151 "encoder_version".to_string(),
152 serde_json::Value::String(version.to_string()),
153 );
154 map.insert("play_settings".to_string(), other);
155 value = serde_json::Value::Object(map);
156 }
157 }
158 value.serialize(serializer)
159 }
160
161 match self {
162 PlaySettingsFile::Legacy(file) => file.serialize(serializer),
163 PlaySettingsFile::V1(file) => with_version(file, "1", serializer),
164 PlaySettingsFile::V2(file) => with_version(file, "2", serializer),
165 PlaySettingsFile::Unknown { raw, .. } => raw.serialize(serializer),
166 }
167 }
168}