sdmmc-core 0.5.0

SD/MMC core data structures and algorithms
Documentation
use crate::register::{Cid, Csd};
use crate::result::{Error, Result};

/// Represents register variants returned in a [R2](crate::response::sd::r2::R2) response in SD mode.
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Register {
    /// Represents the [Cid] card register.
    Cid(Cid),
    /// Represents one of the [Csd] card register variants.
    Csd(Csd),
}

impl Register {
    /// Represents the byte length of the [Register].
    pub const LEN: usize = 16;

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

    /// Attempts to convert a byte slice into a [Register].
    pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
        match Cid::try_from_bytes(val) {
            Ok(cid) => Ok(Self::Cid(cid)),
            _ => match Csd::try_from_bytes(val) {
                Ok(csd) => Ok(Self::Csd(csd)),
                Err(err) => Err(err),
            },
        }
    }

    /// Attempts to convert a byte slice into a [Cid] register variant.
    pub const fn parse_cid(val: &[u8]) -> Result<Self> {
        match Cid::try_from_bytes(val) {
            Ok(cid) => Ok(Self::Cid(cid)),
            Err(err) => Err(err),
        }
    }

    /// Attempts to convert a byte slice into a [Csd] register variant.
    pub const fn parse_csd(val: &[u8]) -> Result<Self> {
        match Csd::try_from_bytes(val) {
            Ok(csd) => Ok(Self::Csd(csd)),
            Err(err) => Err(err),
        }
    }

    /// Attempts to get a reference to a [Cid] variant of the [Register].
    ///
    /// Returns an error if [Register] does not contain a [Cid] variant.
    pub const fn cid(&self) -> Result<&Cid> {
        match self {
            Self::Cid(cid) => Ok(cid),
            _ => Err(Error::invalid_field_variant("register", 1)),
        }
    }

    /// Attempts to get a reference to a [Cid] variant of the [Register].
    ///
    /// Returns an error if [Register] does not contain a [Cid] variant.
    pub const fn into_cid(self) -> Result<Cid> {
        match self {
            Self::Cid(cid) => Ok(cid),
            _ => Err(Error::invalid_field_variant("register", 1)),
        }
    }

    /// Converts a [Cid] into a [Register].
    pub const fn from_cid(val: Cid) -> Self {
        Self::Cid(val)
    }

    /// Attempts to get a reference to a [Csd] variant of the [Register].
    ///
    /// Returns an error if [Register] does not contain a [Csd] variant.
    pub const fn csd(&self) -> Result<&Csd> {
        match self {
            Self::Csd(csd) => Ok(csd),
            _ => Err(Error::invalid_field_variant("register", 0)),
        }
    }

    /// Attempts to into a [Csd] variant of the [Register].
    ///
    /// Returns an error if [Register] does not contain a [Csd] variant.
    pub const fn into_csd(self) -> Result<Csd> {
        match self {
            Self::Csd(csd) => Ok(csd),
            _ => Err(Error::invalid_field_variant("register", 0)),
        }
    }

    /// Converts a [Csd] into a [Register].
    pub const fn from_csd(val: Csd) -> Self {
        Self::Csd(val)
    }

    /// Converts the [Register] into a byte array.
    pub const fn bytes(&self) -> [u8; Self::LEN] {
        match self {
            Self::Cid(cid) => cid.bytes(),
            Self::Csd(csd) => csd.bytes(),
        }
    }
}

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

impl From<Cid> for Register {
    fn from(val: Cid) -> Self {
        Self::from_cid(val)
    }
}

impl From<Csd> for Register {
    fn from(val: Csd) -> Self {
        Self::from_csd(val)
    }
}

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

impl TryFrom<Register> for Cid {
    type Error = Error;

    fn try_from(val: Register) -> Result<Self> {
        val.into_cid()
    }
}

impl TryFrom<Register> for Csd {
    type Error = Error;

    fn try_from(val: Register) -> Result<Self> {
        val.into_csd()
    }
}

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

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

impl<const N: usize> TryFrom<[u8; N]> for Register {
    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 Register {
    type Error = Error;

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