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