1use crate::{invalid_input, BitId, Error, Result};
2use std::{fmt, str};
3
4pub type Bits = u64;
6
7pub const MAX_VALUES: usize = core::mem::size_of::<Bits>() * 8;
9
10pub const MAX_BITS: BitId = MAX_VALUES as _;
12
13pub type Values = Masked<Bits>;
15
16pub trait AsValues {
18 fn bits(&self) -> BitId;
20
21 fn get(&self, id: BitId) -> Option<bool>;
25
26 fn copy_into<T: AsValuesMut>(&self, other: &mut T) {
28 for id in 0..self.bits().min(other.bits()) {
29 other.set(id, self.get(id));
30 }
31 }
32
33 fn convert<T: AsValuesMut + Default>(&self) -> T {
35 let mut other = T::default();
36 self.copy_into(&mut other);
37 other
38 }
39}
40
41pub trait AsValuesMut: AsValues {
43 fn set(&mut self, id: BitId, val: Option<bool>);
47
48 fn with(mut self, id: BitId, val: Option<bool>) -> Self
52 where
53 Self: Sized,
54 {
55 self.set(id, val);
56 self
57 }
58
59 fn copy_from<T: AsValues>(&mut self, other: &T) {
61 for id in 0..self.bits().min(other.bits()) {
62 self.set(id, other.get(id));
63 }
64 }
65
66 fn fill<R: Iterator<Item = BitId>>(&mut self, range: R, val: Option<bool>) {
68 for id in range {
69 self.set(id, val);
70 }
71 }
72
73 fn truncate(&mut self, len: BitId) {
75 for id in len..self.bits() {
76 self.set(id, None);
77 }
78 }
79}
80
81impl<T: AsValues> AsValues for &T {
82 fn bits(&self) -> BitId {
83 (**self).bits()
84 }
85
86 fn get(&self, id: BitId) -> Option<bool> {
87 (**self).get(id)
88 }
89}
90
91impl<T: AsValues> AsValues for &mut T {
92 fn bits(&self) -> BitId {
93 (**self).bits()
94 }
95
96 fn get(&self, id: BitId) -> Option<bool> {
97 (**self).get(id)
98 }
99}
100
101impl<T: AsValuesMut> AsValuesMut for &mut T {
102 fn set(&mut self, id: BitId, val: Option<bool>) {
103 (**self).set(id, val)
104 }
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
109#[repr(C)]
110pub struct Masked<Bits> {
111 pub bits: Bits,
113
114 pub mask: Bits,
116}
117
118macro_rules! as_values {
119 ($($type:ty,)*) => {
120 $(
121 impl AsValues for $type {
122 fn bits(&self) -> BitId {
123 (core::mem::size_of::<$type>() * 8) as _
124 }
125
126 fn get(&self, id: BitId) -> Option<bool> {
127 if id >= (core::mem::size_of::<$type>() * 8) as _ {
128 return None;
129 }
130
131 Some(self & (1 << id) != 0)
132 }
133 }
134
135 impl AsValuesMut for $type {
136 fn set(&mut self, id: BitId, val: Option<bool>) {
137 if id >= (core::mem::size_of::<$type>() * 8) as _ {
138 return;
139 }
140
141 let mask = (1 as $type) << id;
142
143 if let Some(true) = val {
144 *self |= mask;
145 } else {
146 *self &= !mask;
147 }
148 }
149 }
150
151 impl AsValues for Masked<$type> {
152 fn bits(&self) -> BitId {
153 (core::mem::size_of::<$type>() * 8) as _
154 }
155
156 fn get(&self, id: BitId) -> Option<bool> {
157 if id >= (core::mem::size_of::<$type>() * 8) as _ {
158 return None;
159 }
160
161 let mask = (1 as $type) << id;
162
163 if self.mask & mask == 0 {
164 return None;
165 }
166
167 Some(self.bits & mask != 0)
168 }
169 }
170
171 impl AsValuesMut for Masked<$type> {
172 fn set(&mut self, id: BitId, val: Option<bool>) {
173 if id >= (core::mem::size_of::<$type>() * 8) as _ {
174 return;
175 }
176
177 let mask = (1 as $type) << id;
178
179 if let Some(val) = val {
180 self.mask |= mask;
181
182 if val {
183 self.bits |= mask;
184 } else {
185 self.bits &= !mask;
186 }
187 } else {
188 let mask = !mask;
189
190 self.mask &= mask;
191 self.bits &= mask;
192 }
193 }
194 }
195
196 impl From<$type> for Masked<$type> {
197 fn from(bits: $type) -> Self {
198 Self {
199 bits: bits as _,
200 mask: <$type>::MAX as _,
201 }
202 }
203 }
204
205 impl From<Masked<$type>> for $type {
206 fn from(values: Masked<$type>) -> Self {
207 (values.bits & values.mask) as _
208 }
209 }
210
211 impl fmt::Binary for Masked<$type> {
212 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213 use fmt::Write;
214
215 let max = (core::mem::size_of::<$type>() * 8) as BitId;
216 let len = (max - (self.mask & self.bits).leading_zeros() as BitId).max(1);
217 let fill = f.width().map(|width| {
218 let width = if f.alternate() {
219 width - 2
220 } else {
221 width
222 };
223 if width > len as _ {
224 width - len as usize
225 } else {
226 0
227 }
228 }).unwrap_or(0);
229 let (fill_before, fill_after) = match f.align() {
230 Some(fmt::Alignment::Left) => (0, fill),
231 Some(fmt::Alignment::Right) | None => (fill, 0),
232 Some(fmt::Alignment::Center) => (fill - fill / 2, fill / 2),
233 };
234 let fill_char = f.fill();
235 if f.alternate() {
236 f.write_str("0b")?;
237 }
238 for _ in 0..fill_before {
239 f.write_char(fill_char)?;
240 }
241 for i in (0..len).rev() {
242 f.write_char(match self.get(i) {
243 Some(true) => '1',
244 Some(false) => '0',
245 None => 'x',
246 })?;
247 }
248 for _ in 0..fill_after {
249 f.write_char(fill_char)?;
250 }
251 Ok(())
252 }
253 }
254
255 impl fmt::Display for Masked<$type> {
256 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
257 fmt::Binary::fmt(self, f)
258 }
259 }
260
261 impl str::FromStr for Masked<$type> {
262 type Err = Error;
263
264 fn from_str(s: &str) -> Result<Self> {
265 let s = s.strip_prefix("0b").unwrap_or(s);
266 let mut i = s.len() as BitId;
267 if i > (core::mem::size_of::<$type>() * 8) as _ {
268 return Err(invalid_input("Too many line values"));
269 }
270 let mut r = Self::default();
271 for c in s.chars() {
272 i -= 1;
273 match c {
274 '1' => {
275 let b = 1 << i;
276 r.bits |= b;
277 r.mask |= b;
278 }
279 '0' => {
280 let b = 1 << i;
281 r.mask |= b;
282 }
283 'x' => {}
284 _ => return Err(invalid_input("Unexpected char in line value")),
285 }
286 }
287 Ok(r)
288 }
289 }
290
291 )*
292 };
293}
294
295as_values! {
296 u8,
297 u16,
298 u32,
299 u64,
300}
301
302impl AsValues for [bool] {
303 fn bits(&self) -> BitId {
304 self.len() as _
305 }
306
307 fn get(&self, id: BitId) -> Option<bool> {
308 if id >= self.len() as _ {
309 return None;
310 }
311
312 Some(self[id as usize])
313 }
314}
315
316impl AsValuesMut for [bool] {
317 fn set(&mut self, id: BitId, val: Option<bool>) {
318 if id >= self.len() as _ {
319 return;
320 }
321
322 if let Some(val) = val {
323 self[id as usize] = val;
324 }
325 }
326}
327
328impl AsValues for Vec<bool> {
329 fn bits(&self) -> BitId {
330 self.len() as _
331 }
332
333 fn get(&self, id: BitId) -> Option<bool> {
334 if id >= self.len() as _ {
335 return None;
336 }
337
338 Some(self[id as usize])
339 }
340}
341
342impl AsValuesMut for Vec<bool> {
343 fn set(&mut self, id: BitId, val: Option<bool>) {
344 if id >= self.len() as _ {
345 return;
346 }
347
348 if let Some(val) = val {
349 self[id as usize] = val;
350 }
351 }
352}
353
354impl<const LEN: usize> AsValues for [bool; LEN] {
355 fn bits(&self) -> BitId {
356 LEN as _
357 }
358
359 fn get(&self, id: BitId) -> Option<bool> {
360 if id >= LEN as _ {
361 return None;
362 }
363
364 Some(self[id as usize])
365 }
366}
367
368impl<const LEN: usize> AsValuesMut for [bool; LEN] {
369 fn set(&mut self, id: BitId, val: Option<bool>) {
370 if id >= LEN as _ {
371 return;
372 }
373
374 if let Some(val) = val {
375 self[id as usize] = val;
376 }
377 }
378}
379
380impl AsValues for [Option<bool>] {
381 fn bits(&self) -> BitId {
382 self.len() as _
383 }
384
385 fn get(&self, id: BitId) -> Option<bool> {
386 if id >= self.len() as _ {
387 return None;
388 }
389
390 self[id as usize]
391 }
392}
393
394impl AsValuesMut for [Option<bool>] {
395 fn set(&mut self, id: BitId, val: Option<bool>) {
396 if id >= self.len() as _ {
397 return;
398 }
399
400 self[id as usize] = val;
401 }
402}
403
404impl AsValues for Vec<Option<bool>> {
405 fn bits(&self) -> BitId {
406 self.len() as _
407 }
408
409 fn get(&self, id: BitId) -> Option<bool> {
410 if id >= self.len() as _ {
411 return None;
412 }
413
414 self[id as usize]
415 }
416}
417
418impl AsValuesMut for Vec<Option<bool>> {
419 fn set(&mut self, id: BitId, val: Option<bool>) {
420 if id >= self.len() as _ {
421 return;
422 }
423
424 self[id as usize] = val;
425 }
426}
427
428impl<const LEN: usize> AsValues for [Option<bool>; LEN] {
429 fn bits(&self) -> BitId {
430 LEN as _
431 }
432
433 fn get(&self, id: BitId) -> Option<bool> {
434 if id >= LEN as _ {
435 return None;
436 }
437
438 self[id as usize]
439 }
440}
441
442impl<const LEN: usize> AsValuesMut for [Option<bool>; LEN] {
443 fn set(&mut self, id: BitId, val: Option<bool>) {
444 if id >= LEN as _ {
445 return;
446 }
447
448 self[id as usize] = val;
449 }
450}
451
452#[cfg(test)]
453mod test {
454 use super::*;
455
456 #[test]
457 fn format_masked() {
458 assert_eq!(Masked::from(0b1000u8).to_string(), "1000");
459
460 assert_eq!(
461 Values {
462 bits: 0b1000,
463 mask: 0b1111,
464 }
465 .to_string(),
466 "1000"
467 );
468
469 assert_eq!(
470 Values {
471 bits: 0b0011,
472 mask: 0b0111,
473 }
474 .to_string(),
475 "11"
476 );
477
478 assert_eq!(
479 Values {
480 bits: 0b0011,
481 mask: 0b1111,
482 }
483 .to_string(),
484 "11"
485 );
486
487 assert_eq!(
488 Values {
489 bits: 0b11000,
490 mask: 0b00011,
491 }
492 .to_string(),
493 "0"
494 );
495
496 assert_eq!(
497 Values {
498 bits: 0b100001,
499 mask: 0b110011,
500 }
501 .to_string(),
502 "10xx01"
503 );
504 }
505
506 #[test]
507 fn format_masked_advanced() {
508 assert_eq!(format!("{:#}", Masked::from(0b1000u8)), "0b1000");
509
510 assert_eq!(format!("{:#08b}", 0b1000u8), "0b001000");
511
512 assert_eq!(format!("{:11}", Masked::from(0b1000u8)), " 1000");
515
516 assert_eq!(format!("{:-<11}", Masked::from(0b1000u8)), "1000-------");
517
518 assert_eq!(format!("{:->11}", Masked::from(0b1000u8)), "-------1000");
519
520 assert_eq!(format!("{:-^11}", Masked::from(0b1000u8)), "----1000---");
521 }
522
523 #[test]
524 fn parse_masked() {
525 assert_eq!(
526 "0110".parse::<Values>().unwrap(),
527 Values {
528 bits: 0b0110,
529 mask: 0b1111,
530 }
531 );
532
533 assert_eq!(
534 "00110".parse::<Values>().unwrap(),
535 Values {
536 bits: 0b00110,
537 mask: 0b11111,
538 }
539 );
540
541 assert_eq!(
542 "0b10101".parse::<Values>().unwrap(),
543 Values {
544 bits: 0b10101,
545 mask: 0b11111,
546 }
547 );
548
549 assert_eq!(
550 "1x10x".parse::<Values>().unwrap(),
551 Values {
552 bits: 0b10100,
553 mask: 0b10110,
554 }
555 );
556
557 assert_eq!(
558 "xx0x010".parse::<Values>().unwrap(),
559 Values {
560 bits: 0b00010,
561 mask: 0b10111,
562 }
563 );
564
565 assert_eq!(
566 "0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
567 .parse::<Values>()
568 .unwrap(),
569 Values::default()
570 );
571
572 assert_eq!(
573 "0b1111111111111111111111111111111111111111111111111111111111111111"
574 .parse::<Values>()
575 .unwrap(),
576 Values {
577 bits: Bits::MAX,
578 mask: Bits::MAX,
579 }
580 );
581
582 assert_eq!(
583 "0b0000000000000000000000000000000000000000000000000000000000000000"
584 .parse::<Values>()
585 .unwrap(),
586 Values {
587 bits: 0,
588 mask: Bits::MAX,
589 }
590 );
591
592 assert!(
593 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
594 .parse::<Values>()
595 .is_err()
596 );
597
598 assert!("0b10xy".parse::<Values>().is_err());
599 }
600}