use crate::error::{AudioError, AudioResult};
#[derive(Debug, Clone)]
pub struct AudioDevice {
id: String,
name: String,
}
impl AudioDevice {
pub fn new(id: impl Into<String>, name: impl Into<String>) -> Self {
Self { id: id.into(), name: name.into() }
}
pub fn id(&self) -> &str {
&self.id
}
pub fn name(&self) -> &str {
&self.name
}
}
#[derive(Debug, Clone)]
pub struct CaptureConfig {
pub sample_rate: u32,
pub channels: u8,
pub frame_duration_ms: u32,
}
impl CaptureConfig {
pub fn validate(&self) -> AudioResult<()> {
if self.sample_rate == 0 {
return Err(AudioError::Device("invalid sample rate: 0".into()));
}
if self.channels == 0 {
return Err(AudioError::Device("invalid channel count: 0".into()));
}
if self.frame_duration_ms == 0 {
return Err(AudioError::Device("invalid frame duration: 0 ms".into()));
}
Ok(())
}
}
impl Default for CaptureConfig {
fn default() -> Self {
Self { sample_rate: 16000, channels: 1, frame_duration_ms: 20 }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_audio_device_accessors() {
let device = AudioDevice::new("dev-123", "Test Microphone");
assert_eq!(device.id(), "dev-123");
assert_eq!(device.name(), "Test Microphone");
}
#[test]
fn test_audio_device_clone() {
let device = AudioDevice::new("id", "name");
let cloned = device.clone();
assert_eq!(cloned.id(), device.id());
assert_eq!(cloned.name(), device.name());
}
#[test]
fn test_capture_config_defaults() {
let config = CaptureConfig::default();
assert_eq!(config.sample_rate, 16000);
assert_eq!(config.channels, 1);
assert_eq!(config.frame_duration_ms, 20);
}
#[test]
fn test_capture_config_validate_ok() {
let config = CaptureConfig::default();
assert!(config.validate().is_ok());
}
#[test]
fn test_capture_config_validate_zero_sample_rate() {
let config = CaptureConfig { sample_rate: 0, ..Default::default() };
let err = config.validate().unwrap_err();
assert!(matches!(err, AudioError::Device(msg) if msg.contains("sample rate")));
}
#[test]
fn test_capture_config_validate_zero_channels() {
let config = CaptureConfig { channels: 0, ..Default::default() };
let err = config.validate().unwrap_err();
assert!(matches!(err, AudioError::Device(msg) if msg.contains("channel count")));
}
#[test]
fn test_capture_config_validate_zero_frame_duration() {
let config = CaptureConfig { frame_duration_ms: 0, ..Default::default() };
let err = config.validate().unwrap_err();
assert!(matches!(err, AudioError::Device(msg) if msg.contains("frame duration")));
}
}