use std::fmt::{self, Display, Formatter};
use crate::ffi;
const BAR_COUNT_MIN: u16 = 1;
const BAR_COUNT_MAX: u16 = 256;
const FRAMERATE_MIN: u32 = 1;
const FRAMERATE_MAX: u32 = 360;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BarCount(u16);
impl BarCount {
pub const DEFAULT: Self = Self(20);
#[must_use]
pub fn new(value: u16) -> Self {
Self(value.clamp(BAR_COUNT_MIN, BAR_COUNT_MAX))
}
#[must_use]
pub fn value(self) -> u16 {
self.0
}
#[must_use]
pub(crate) fn adjusted_for_stereo(self, stereo: bool) -> Self {
if stereo && !self.0.is_multiple_of(2) {
Self(self.0.saturating_add(1).min(BAR_COUNT_MAX))
} else {
self
}
}
}
impl Default for BarCount {
fn default() -> Self {
Self::DEFAULT
}
}
impl Display for BarCount {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<u16> for BarCount {
fn from(value: u16) -> Self {
Self::new(value)
}
}
impl From<i32> for BarCount {
fn from(value: i32) -> Self {
Self::new(value.clamp(BAR_COUNT_MIN as i32, BAR_COUNT_MAX as i32) as u16)
}
}
impl From<usize> for BarCount {
fn from(value: usize) -> Self {
let clamped = value.min(BAR_COUNT_MAX as usize) as u16;
Self::new(clamped)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Framerate(u32);
impl Framerate {
pub const DEFAULT: Self = Self(60);
#[must_use]
pub fn new(value: u32) -> Self {
Self(value.clamp(FRAMERATE_MIN, FRAMERATE_MAX))
}
#[must_use]
pub fn value(self) -> u32 {
self.0
}
}
impl Default for Framerate {
fn default() -> Self {
Self::DEFAULT
}
}
impl Display for Framerate {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<u32> for Framerate {
fn from(value: u32) -> Self {
Self::new(value)
}
}
impl From<i32> for Framerate {
fn from(value: i32) -> Self {
Self::new(value.clamp(FRAMERATE_MIN as i32, FRAMERATE_MAX as i32) as u32)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum InputMethod {
Fifo,
PortAudio,
PipeWire,
Alsa,
Pulse,
Sndio,
Oss,
Jack,
Shmem,
Winscap,
}
impl From<InputMethod> for ffi::InputMethod {
fn from(method: InputMethod) -> Self {
match method {
InputMethod::Fifo => ffi::InputMethod::Fifo,
InputMethod::PortAudio => ffi::InputMethod::PortAudio,
InputMethod::PipeWire => ffi::InputMethod::PipeWire,
InputMethod::Alsa => ffi::InputMethod::Alsa,
InputMethod::Pulse => ffi::InputMethod::Pulse,
InputMethod::Sndio => ffi::InputMethod::Sndio,
InputMethod::Oss => ffi::InputMethod::Oss,
InputMethod::Jack => ffi::InputMethod::Jack,
InputMethod::Shmem => ffi::InputMethod::Shmem,
InputMethod::Winscap => ffi::InputMethod::Winscap,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bar_count_clamps_zero_to_minimum() {
assert_eq!(BarCount::new(0).value(), BAR_COUNT_MIN);
}
#[test]
fn bar_count_clamps_above_max() {
assert_eq!(BarCount::new(BAR_COUNT_MAX + 1).value(), BAR_COUNT_MAX);
}
#[test]
fn bar_count_preserves_valid_value() {
assert_eq!(BarCount::new(128).value(), 128);
}
#[test]
fn bar_count_from_usize_clamps_above_max() {
let large: usize = 1000;
assert_eq!(BarCount::from(large).value(), BAR_COUNT_MAX);
}
#[test]
fn bar_count_from_usize_zero_clamps_to_minimum() {
assert_eq!(BarCount::from(0_usize).value(), BAR_COUNT_MIN);
}
#[test]
fn bar_count_adjusted_for_stereo_rounds_odd_up() {
assert_eq!(BarCount::new(21).adjusted_for_stereo(true).value(), 22);
}
#[test]
fn bar_count_adjusted_for_stereo_preserves_even() {
assert_eq!(BarCount::new(20).adjusted_for_stereo(true).value(), 20);
}
#[test]
fn bar_count_adjusted_for_stereo_unchanged_when_mono() {
assert_eq!(BarCount::new(21).adjusted_for_stereo(false).value(), 21);
}
#[test]
fn bar_count_adjusted_for_stereo_at_max_boundary() {
assert_eq!(BarCount::new(255).adjusted_for_stereo(true).value(), 256);
}
#[test]
fn bar_count_adjusted_for_stereo_at_min_boundary() {
assert_eq!(BarCount::new(1).adjusted_for_stereo(true).value(), 2);
}
#[test]
fn framerate_clamps_zero_to_minimum() {
assert_eq!(Framerate::new(0).value(), FRAMERATE_MIN);
}
#[test]
fn framerate_clamps_above_max() {
assert_eq!(Framerate::new(FRAMERATE_MAX + 1).value(), FRAMERATE_MAX);
}
#[test]
fn framerate_preserves_valid_value() {
assert_eq!(Framerate::new(144).value(), 144);
}
}