diff options
Diffstat (limited to '')
| -rw-r--r-- | src/config.rs | 35 |
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(()) |
