mpdclient 0.2.0

Rust interface to MPD using libmpdclient
Documentation
use mpdclient_sys::{
    MPD_SAMPLE_FORMAT_DSD, MPD_SAMPLE_FORMAT_FLOAT, MPD_SAMPLE_FORMAT_UNDEFINED, mpd_audio_format,
};

/// Format of a raw PCM stream.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AudioFormat {
    /// Sample rate  in Hz. One frame in Stereo contains two samples.
    pub sample_rate: Option<u32>,

    /// Number of significant bits per sample
    pub bits: SupportedBits,

    /// Number of channels. Currently MPD only completely works with [`Channels::Mono`] and
    /// [`Channels::Stereo`].
    pub channels: Channels,
}

impl From<mpd_audio_format> for AudioFormat {
    fn from(value: mpd_audio_format) -> Self {
        let sample_rate = if value.sample_rate == 0 {
            None
        } else {
            Some(value.sample_rate)
        };
        AudioFormat {
            sample_rate,
            bits: SupportedBits::from(value.bits),
            channels: Channels::from(value.channels),
        }
    }
}

/// Describes all supported bit counts/formats supported by MPD.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(clippy::cast_possible_wrap)]
pub enum SupportedBits {
    /// Sample format is not specified or unknown
    Undefined = MPD_SAMPLE_FORMAT_UNDEFINED as isize,

    /// 8 significant bits per sample
    N8 = 8,

    /// 16 significant bits per sample
    N16 = 16,

    /// 24 significant bits per sample
    N24 = 24,

    /// 24 significant bits per sample
    N32 = 32,

    /// 32 bit floating point samples
    Float = MPD_SAMPLE_FORMAT_FLOAT as isize,

    /// DSD samples
    DSD = MPD_SAMPLE_FORMAT_DSD as isize,
}

impl From<u8> for SupportedBits {
    fn from(value: u8) -> Self {
        match value {
            // MPD_SAMPLE_FORMAT_UNDEFINED
            0 => Self::Undefined,
            8 => Self::N8,
            16 => Self::N16,
            24 => Self::N24,
            32 => Self::N32,
            // MPD_SAMPLE_FORMAT_FLOAT
            0xe0 => Self::Float,
            // MPD_SAMPLE_FORMAT_DSD
            0xe1 => Self::DSD,
            _ => unreachable!(),
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
/// Supported audio channels by MPD.
pub enum Channels {
    /// Unknown or unspecified number of channels.
    Unknown = 0,

    /// One channel.
    Mono = 1,

    /// Two channels.
    Stereo = 2,
}

impl From<u8> for Channels {
    fn from(value: u8) -> Self {
        match value {
            0 => Self::Unknown,
            1 => Self::Mono,
            2 => Self::Stereo,
            _ => unimplemented!(),
        }
    }
}