use crate::register::{Cid, Csd};
use crate::response::Start;
use crate::result::{Error, Result};
use crate::{lib_bitfield, response};
mod register;
pub use register::Register;
lib_bitfield! {
pub R2(MSB0 [u8; 17]): u128 {
raw_start: 135, 128;
raw_register: 127, 0;
}
}
response! {
R2 {
response_mode: Sd,
}
}
impl R2 {
pub const LEN: usize = 17;
pub const DEFAULT: [u8; Self::LEN] = [0x3f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x13];
pub const fn new() -> Self {
Self(Self::DEFAULT)
}
pub const fn start(&self) -> Result<Start> {
Start::try_from_bits(self.raw_start() as u8)
}
pub const fn register(&self) -> Result<Register> {
Register::try_from_bytes(&self.raw_register().to_be_bytes())
}
pub fn set_register(&mut self, val: Register) {
self.set_raw_register(u128::from_be_bytes(val.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)),
_ => {
let r = Self([
val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9],
val[10], val[11], val[12], val[13], val[14], val[15], val[16],
]);
match (r.start(), r.register()) {
(Ok(_), Ok(_)) => Ok(r),
(Err(_err), _) => Err(Error::invalid_field_variant(
"r2::start",
r.raw_start() as usize,
)),
(_, Err(err)) => Err(err),
}
}
}
}
}
impl Default for R2 {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_valid() {
let mut r2 = R2::new();
let start = Start::from_bits(0x3f);
let register = Register::new();
let cid = Cid::new();
let csd = Csd::new();
let r2_bytes = R2::DEFAULT;
let raw_crc = r2_bytes[16];
assert_eq!(
r2.register().and_then(|r| r.cid().map(|c| c.crc().bits())),
Ok(raw_crc)
);
assert_eq!(R2::try_from_bytes(r2_bytes.as_ref()), Ok(r2));
assert_eq!(r2.bytes(), r2_bytes);
assert_eq!(r2.start(), Ok(start));
assert_eq!(r2.register(), Ok(register));
assert_eq!(r2.register().unwrap().cid(), Ok(&cid));
r2.set_register(csd.into());
assert_eq!(r2.register().unwrap().csd(), Ok(&csd));
}
}