aboutsummaryrefslogtreecommitdiffstats
path: root/src/config.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.rs')
-rw-r--r--src/config.rs35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/config.rs b/src/config.rs
index a08f01f..52afd92 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -25,6 +25,8 @@ pub struct Config {
25 pub volume: Option<u8>, 25 pub volume: Option<u8>,
26 pub shuffle: Option<String>, 26 pub shuffle: Option<String>,
27 pub display_format: Option<String>, 27 pub display_format: Option<String>,
28 /// Output sample rate: `None` follows the track, `Some` forces a rate.
29 pub sample_rate: Option<String>,
28} 30}
29 31
30/// Identity of the config file on disk, used to tell whether a cached copy is 32/// Identity of the config file on disk, used to tell whether a cached copy is
@@ -64,6 +66,7 @@ impl Config {
64 volume: Some(50), 66 volume: Some(50),
65 shuffle: None, 67 shuffle: None,
66 display_format: Some(String::from("$ARTIST - $TRACK")), 68 display_format: Some(String::from("$ARTIST - $TRACK")),
69 sample_rate: None,
67 }; 70 };
68 default.save()?; 71 default.save()?;
69 return Ok(default); 72 return Ok(default);
@@ -192,6 +195,8 @@ impl Config {
192 output.push_str(&format!("shuffle = \"{}\"\n", shuffle)); 195 output.push_str(&format!("shuffle = \"{}\"\n", shuffle));
193 let fmt = self.display_format.clone().unwrap_or_default(); 196 let fmt = self.display_format.clone().unwrap_or_default();
194 output.push_str(&format!("display_format = \"{}\"\n", fmt)); 197 output.push_str(&format!("display_format = \"{}\"\n", fmt));
198 let sample_rate = self.sample_rate.as_deref().unwrap_or("auto");
199 output.push_str(&format!("sample_rate = \"{}\"\n", sample_rate));
195 if let Some(parent) = self.config_path.parent() { 200 if let Some(parent) = self.config_path.parent() {
196 fs::create_dir_all(parent)?; 201 fs::create_dir_all(parent)?;
197 } 202 }
@@ -207,6 +212,11 @@ impl Config {
207 Ok(()) 212 Ok(())
208 } 213 }
209 214
215 /// Forced output rate, or `None` to follow each track.
216 pub fn sample_rate_hz(&self) -> Option<u32> {
217 self.sample_rate.as_deref().and_then(|s| s.parse().ok())
218 }
219
210 pub fn get(&self, key: &str) -> Result<String, Box<dyn std::error::Error>> { 220 pub fn get(&self, key: &str) -> Result<String, Box<dyn std::error::Error>> {
211 match key { 221 match key {
212 "music_paths" => Ok(self 222 "music_paths" => Ok(self
@@ -252,6 +262,10 @@ impl Config {
252 .display_format 262 .display_format
253 .clone() 263 .clone()
254 .unwrap_or_else(|| "not set".to_string())), 264 .unwrap_or_else(|| "not set".to_string())),
265 "sample_rate" => Ok(self
266 .sample_rate
267 .clone()
268 .unwrap_or_else(|| "auto".to_string())),
255 _ => Err(format!("Unknown setting: {}", key).into()), 269 _ => Err(format!("Unknown setting: {}", key).into()),
256 } 270 }
257 } 271 }
@@ -291,6 +305,20 @@ impl Config {
291 "display_format" => { 305 "display_format" => {
292 self.display_format = Some(value.to_string()); 306 self.display_format = Some(value.to_string());
293 } 307 }
308 "sample_rate" => {
309 let value = value.trim();
310 if value.eq_ignore_ascii_case("auto") || value == "off" {
311 self.sample_rate = None;
312 } else {
313 let rate: u32 = value
314 .parse()
315 .map_err(|_| format!("Invalid sample rate: {}", value))?;
316 if !(8_000..=384_000).contains(&rate) {
317 return Err(format!("Sample rate must be 8000-384000 Hz: {}", value).into());
318 }
319 self.sample_rate = Some(rate.to_string());
320 }
321 }
294 _ => return Err(format!("Unknown setting: {}", key).into()), 322 _ => return Err(format!("Unknown setting: {}", key).into()),
295 } 323 }
296 Ok(()) 324 Ok(())
@@ -357,6 +385,12 @@ impl Config {
357 .clone() 385 .clone()
358 .unwrap_or_else(|| "not set".to_string()) 386 .unwrap_or_else(|| "not set".to_string())
359 ); 387 );
388 println!(
389 "sample_rate = {}",
390 self.sample_rate
391 .clone()
392 .unwrap_or_else(|| "auto".to_string())
393 );
360 } 394 }
361 395
362 pub fn unset(&mut self, key: &str) -> Result<(), Box<dyn std::error::Error>> { 396 pub fn unset(&mut self, key: &str) -> Result<(), Box<dyn std::error::Error>> {
@@ -370,6 +404,7 @@ impl Config {
370 "volume" => self.volume = None, 404 "volume" => self.volume = None,
371 "shuffle" => self.shuffle = None, 405 "shuffle" => self.shuffle = None,
372 "display_format" => self.display_format = None, 406 "display_format" => self.display_format = None,
407 "sample_rate" => self.sample_rate = None,
373 _ => return Err(format!("Unknown setting: {}", key).into()), 408 _ => return Err(format!("Unknown setting: {}", key).into()),
374 } 409 }
375 Ok(()) 410 Ok(())