sdmmc-core 0.5.0

SD/MMC core data structures and algorithms
Documentation
//! Device-Specific Register (`DSR`).

use crate::lib_bitfield;
use crate::result::{Error, Result};

lib_bitfield! {
    /// Represents the `DSR` card register.
    pub Dsr(u16): u16 {
        pub inner: 15, 0;
    }
}

impl Dsr {
    /// Represents the byte length of the [Dsr].
    pub const LEN: usize = 2;
    /// Represents the default level of the [Dsr].
    pub const DEFAULT: u16 = 0x404;

    /// Creates a new [Dsr].
    pub const fn new() -> Self {
        Self(Self::DEFAULT)
    }

    /// Converts the [Dsr] into a byte array.
    pub const fn bytes(&self) -> [u8; Self::LEN] {
        self.0.to_be_bytes()
    }

    /// Converts a [`u16`] into a [Dsr].
    pub const fn from_bits(val: u16) -> Self {
        Self(val)
    }

    /// Attempts to convert a byte slice into a [Dsr].
    pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
        match val.len() {
            len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
            _ => Ok(Self(u16::from_be_bytes([val[0], val[1]]))),
        }
    }
}

impl Default for Dsr {
    fn default() -> Self {
        Self::new()
    }
}

impl From<u16> for Dsr {
    fn from(val: u16) -> Self {
        Self::from_bits(val)
    }
}

impl From<Dsr> for u16 {
    fn from(val: Dsr) -> Self {
        val.bits()
    }
}

impl From<Dsr> for [u8; Dsr::LEN] {
    fn from(val: Dsr) -> Self {
        val.bytes()
    }
}

impl TryFrom<&[u8]> for Dsr {
    type Error = Error;

    fn try_from(val: &[u8]) -> Result<Self> {
        Self::try_from_bytes(val)
    }
}

impl<const N: usize> TryFrom<&[u8; N]> for Dsr {
    type Error = Error;

    fn try_from(val: &[u8; N]) -> Result<Self> {
        Self::try_from_bytes(val.as_ref())
    }
}

impl<const N: usize> TryFrom<[u8; N]> for Dsr {
    type Error = Error;

    fn try_from(val: [u8; N]) -> Result<Self> {
        Self::try_from_bytes(val.as_ref())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_fields() {
        (1..=u16::BITS)
            .map(|r| ((1u32 << r) - 1) as u16)
            .for_each(|raw_dsr| {
                let raw = raw_dsr.to_be_bytes();
                let exp_dsr = Dsr(raw_dsr);

                assert_eq!(Dsr::from_bits(raw_dsr), exp_dsr);
                assert_eq!(Dsr::try_from_bytes(&raw), Ok(exp_dsr));
                assert_eq!(Dsr::try_from(&raw), Ok(exp_dsr));
                assert_eq!(Dsr::try_from(raw), Ok(exp_dsr));

                assert_eq!(exp_dsr.bits(), raw_dsr);
                assert_eq!(exp_dsr.inner(), raw_dsr);
                assert_eq!(exp_dsr.bytes(), raw);
            });
    }
}