sdmmc_core/command/class/class8/acmd42/
arg.rs1use crate::lib_bitfield;
2use crate::result::{Error, Result};
3
4mod cd;
5
6pub use cd::*;
7
8lib_bitfield! {
9 pub Argument(u32): u8 {
11 raw_set_cd: 0;
12 }
13}
14
15impl Argument {
16 pub const LEN: usize = 4;
18 pub const DEFAULT: u32 = 0;
20
21 pub const fn new() -> Self {
23 Self(0)
24 }
25
26 pub const fn set_cd(&self) -> CardDetect {
28 CardDetect::from_bool(self.raw_set_cd())
29 }
30
31 pub fn set_set_cd(&mut self, val: CardDetect) {
33 self.set_raw_set_cd(val.into_bool());
34 }
35
36 pub const fn try_from_bits(val: u32) -> Result<Self> {
38 Ok(Self(val))
39 }
40
41 pub const fn bytes(&self) -> [u8; Self::LEN] {
43 self.0.to_be_bytes()
44 }
45
46 pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
48 match val.len() {
49 len if len < Self::LEN => Err(Error::invalid_length(len, Self::LEN)),
50 _ => Self::try_from_bits(u32::from_be_bytes([val[0], val[1], val[2], val[3]])),
51 }
52 }
53}
54
55impl Default for Argument {
56 fn default() -> Self {
57 Self::new()
58 }
59}
60
61impl TryFrom<u32> for Argument {
62 type Error = Error;
63
64 fn try_from(val: u32) -> Result<Self> {
65 Self::try_from_bits(val)
66 }
67}
68
69impl From<Argument> for u32 {
70 fn from(val: Argument) -> Self {
71 val.bits()
72 }
73}
74
75impl From<Argument> for [u8; Argument::LEN] {
76 fn from(val: Argument) -> Self {
77 val.bytes()
78 }
79}
80
81impl TryFrom<&[u8]> for Argument {
82 type Error = Error;
83
84 fn try_from(val: &[u8]) -> Result<Self> {
85 Self::try_from_bytes(val)
86 }
87}
88
89impl<const N: usize> TryFrom<&[u8; N]> for Argument {
90 type Error = Error;
91
92 fn try_from(val: &[u8; N]) -> Result<Self> {
93 Self::try_from_bytes(val.as_ref())
94 }
95}
96
97impl<const N: usize> TryFrom<[u8; N]> for Argument {
98 type Error = Error;
99
100 fn try_from(val: [u8; N]) -> Result<Self> {
101 Self::try_from_bytes(val.as_ref())
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn test_fields() {
111 let new_set_cd = CardDetect::new();
112
113 (1..=u32::BITS)
114 .map(|r| ((1u64 << r) - 1) as u32)
115 .for_each(|raw_arg| {
116 let raw = raw_arg.to_be_bytes();
117
118 match Argument::try_from_bits(raw_arg) {
119 Ok(mut exp_arg) => {
120 let exp_set_cd = CardDetect::from_bool((raw_arg & 0b1) != 0);
121
122 assert_eq!(Argument::try_from_bits(raw_arg), Ok(exp_arg));
123 assert_eq!(Argument::try_from_bytes(&raw), Ok(exp_arg));
124 assert_eq!(Argument::try_from(raw_arg), Ok(exp_arg));
125 assert_eq!(Argument::try_from(raw), Ok(exp_arg));
126 assert_eq!(Argument::try_from(&raw), Ok(exp_arg));
127
128 assert_eq!(exp_arg.set_cd(), exp_set_cd);
129
130 exp_arg.set_set_cd(new_set_cd);
131 assert_eq!(exp_arg.set_cd(), new_set_cd);
132
133 exp_arg.set_set_cd(exp_set_cd);
134 assert_eq!(exp_arg.set_cd(), exp_set_cd);
135 }
136 Err(err) => {
137 let exp_err = Error::invalid_field_variant(
138 "command::argument::set_cd",
139 (raw_arg & 0b11) as usize,
140 );
141 assert_eq!(err, exp_err);
142 assert_eq!(Argument::try_from_bytes(&raw), Err(exp_err));
143 assert_eq!(Argument::try_from(raw_arg), Err(exp_err));
144 assert_eq!(Argument::try_from(raw), Err(exp_err));
145 assert_eq!(Argument::try_from(&raw), Err(exp_err));
146 }
147 }
148 });
149 }
150}