use crate::response::sdio::r1::R1;
use crate::result::{Error, Result};
use crate::{lib_bitfield, response};
lib_bitfield! {
pub R5(u16): u8 {
raw_r1: 15, 8;
raw_data: 7, 0;
}
}
response! {
R5 {
response_mode: Spi,
}
}
impl R5 {
pub const LEN: usize = 2;
pub const DEFAULT: u16 = 0;
pub const fn new() -> Self {
Self(Self::DEFAULT)
}
pub const fn r1(&self) -> Result<R1> {
R1::try_from_bits(self.raw_r1())
}
pub fn set_r1(&mut self, val: R1) {
self.set_raw_r1(val.bits() as u16);
}
pub const fn data(&self) -> u8 {
self.raw_data()
}
pub fn set_data(&mut self, val: u8) {
self.set_raw_data(val as u16);
}
pub const fn try_from_bits(val: u16) -> Result<Self> {
Self::try_from_bytes(&val.to_be_bytes())
}
pub const fn bytes(&self) -> [u8; Self::LEN] {
self.0.to_be_bytes()
}
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)),
_ if R1::try_from_bits(val[0]).is_err() => {
Err(Error::invalid_field_variant("r5::r1", val[0] as usize))
}
_ => Ok(Self(u16::from_be_bytes([val[0], val[1]]))),
}
}
}
impl Default for R5 {
fn default() -> Self {
Self::new()
}
}
impl TryFrom<u16> for R5 {
type Error = Error;
fn try_from(val: u16) -> Result<Self> {
Self::try_from_bits(val)
}
}
impl From<R5> for u16 {
fn from(val: R5) -> Self {
val.bits()
}
}
impl TryFrom<&[u8]> for R5 {
type Error = Error;
fn try_from(val: &[u8]) -> Result<Self> {
Self::try_from_bytes(val)
}
}
impl<const N: usize> TryFrom<[u8; N]> for R5 {
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 R5 {
type Error = Error;
fn try_from(val: &[u8; N]) -> Result<Self> {
Self::try_from_bytes(val.as_ref())
}
}
impl From<R5> for [u8; R5::LEN] {
fn from(val: R5) -> Self {
val.bytes()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_field;
#[test]
fn test_fields() {
let r5 = R5::new();
let r1 = r5.r1().unwrap();
assert!(!r1.idle());
assert!(!r1.illegal_command());
assert!(!r1.crc_error());
assert!(!r1.function_number_error());
assert!(!r1.parameter_error());
assert_eq!(r5.data(), 0);
(0..=u8::MAX).zip(0..=u8::MAX).for_each(|(r1, data)| {
let raw = [r1, data];
let raw_r5 = u16::from_be_bytes(raw);
match R5::try_from_bytes(raw.as_ref()) {
Ok(mut r5) => {
assert_eq!(R5::try_from_bytes(raw.as_ref()), Ok(r5));
assert_eq!(R5::try_from(raw), Ok(r5));
let mut r1 = r5.r1().unwrap();
test_field!(r1, idle: 0);
test_field!(r1, illegal_command: 2);
test_field!(r1, crc_error: 3);
test_field!(r1, function_number_error: 4);
test_field!(r1, parameter_error: 6);
r5.set_r1(R1::new());
assert_eq!(r5.r1(), Ok(R1::new()));
r5.set_r1(r1);
assert_eq!(r5.r1(), Ok(r1));
assert_eq!(r5.data(), data);
r5.set_data(0);
assert_eq!(r5.data(), 0);
r5.set_data(data);
assert_eq!(r5.data(), data);
}
Err(_) => {
assert_eq!(
R5::try_from_bytes(raw.as_ref()),
Err(Error::invalid_field_variant("r5::r1", r1 as usize))
);
assert_eq!(
R5::try_from(raw),
Err(Error::invalid_field_variant("r5::r1", r1 as usize))
);
}
}
});
}
}