From 87b406d7095b2b69cf2dd8b44a5668a8baa47002 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Fri, 13 Nov 2026 10:50:15 +0000 Subject: [PATCH] Preserve unsupported session sample rates on decode --- crates/time/src/soundcraft/mod.rs | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/crates/time/src/soundcraft/mod.rs b/crates/time/src/soundcraft/mod.rs index 300909003..075a2ade7 100644 --- a/crates/time/src/soundcraft/mod.rs +++ b/crates/time/src/soundcraft/mod.rs @@ -36,18 +36,14 @@ pub enum TimeError { Meter(u32, u32), } -/// Sample rates supported by sessions (Pro Tools offers 44.1 k – 192 k; we accept 8 k – 768 k). +/// Session sample rate stored as the original wire value. +/// +/// `new` validates values created by the application. Deserialization remains +/// permissive so legacy or damaged sessions retain their original value and +/// can be diagnosed by the application instead of failing before recovery. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -#[serde(try_from = "u32")] pub struct SampleRate(u32); -impl TryFrom for SampleRate { - type Error = TimeError; - fn try_from(hz: u32) -> Result { - Self::new(hz) - } -} - impl SampleRate { pub const HZ_44100: SampleRate = SampleRate(44_100); pub const HZ_48000: SampleRate = SampleRate(48_000); @@ -59,6 +55,10 @@ impl SampleRate { pub fn hz(self) -> u32 { self.0 } + /// Whether this wire value is supported for normal session operation. + pub fn is_supported(self) -> bool { + (8_000..=768_000).contains(&self.0) + } pub fn as_f64(self) -> f64 { f64::from(self.0) } @@ -132,12 +132,17 @@ mod tests { use super::*; #[test] - fn sample_rate_serde_validates_nonzero_bounds() { - assert!(serde_json::from_str::("0").is_err()); - assert!(serde_json::from_str::("7999").is_err()); + fn sample_rate_serde_preserves_unsupported_wire_values_for_recovery() { + for wire in [0, 7_999, 768_001, u32::MAX] { + let rate: SampleRate = serde_json::from_value(serde_json::json!(wire)).unwrap(); + assert_eq!(rate.hz(), wire); + assert!(!rate.is_supported()); + assert_eq!(serde_json::to_value(rate).unwrap(), serde_json::json!(wire)); + } let rate = SampleRate::new(48_000).unwrap(); assert_eq!(serde_json::to_string(&rate).unwrap(), "48000"); assert_eq!(serde_json::from_str::("48000").unwrap(), rate); + assert!(rate.is_supported()); } #[test]