bobbin_bits/
lib.rs

1#![no_std]
2//! # bobbin-bits
3//!
4//!bobbin-bits defines types representing binary numbers of width 1 to 32 and ranged values from 1 to 32. These are useful for representing small bit fields and for indexing small collections.
5//!
6//!## Motivation
7//!
8//!Rust doesn't currently have direct support for unsigned integer types for widths other than u8, u16, u32, u64 and u128 or for ranged integers. Applications instead must store values in a larger primitive type and then check
9//!that the values stay in the correct range, typically at function boundaries. This is error prone and can
10//!impact performance.
11//!
12//!One solution is to define structs or enums to represent domain-specific values that are known to be in a specific range. This can eliminate run-time range checks at the cost of a large amount of boilerplate for managing conversions to and from these values. 
13//!
14//!For some APIs the code for managing these types ends up much larger than the API itself.
15//!It can also prove to be a significant documentation challenge and barrier to learning the API. Having a unique type for almost every function parameter in an API is undesirable.
16//!
17//!This crate takes a different approach, defining a set of general-purpose types useful 
18//!for representing bit fields <= 32 bits and integer ranges from 1 through 32. Conversion
19//!traits are defined to and from Rust unsigned integer types and i32, performing
20//!range checking where needed.
21//!
22//!## Panics
23//!
24//!These types will panic if a conversion fails because the value is out of range for the
25//!destination type.
26//!
27//!## Representation
28//!
29//!Types U1 through U6 are enums with repr(u8), allowing exhaustive matching without a default
30//!case. Their members are named with the prefix "B" followed by the
31//!n-bit binary representation of that number, like this:
32//!
33//!```
34//!#[repr(u8)]
35//!pub enum U3 {
36//!    B000 = 0b000,
37//!    B001 = 0b001,
38//!    B010 = 0b010,
39//!    B011 = 0b011,
40//!    B100 = 0b100,
41//!    B101 = 0b101,
42//!    B110 = 0b110,
43//!    B111 = 0b111,
44//!}
45//!```
46//!
47//!
48//!Similarly, R1 through R32 are enums with repr(usize). Their members are named with
49//!the prefix "X" followed by the hexadecimal represention of the number, single digits
50//!for 0-15 and two digits for 16-32:
51//!
52//!```
53//!#[repr(usize)]
54//!pub enum R12 {
55//!    X0 = 0x0,
56//!    X1 = 0x1,
57//!    X2 = 0x2,
58//!    X3 = 0x3,
59//!    X4 = 0x4,
60//!    X5 = 0x5,
61//!    X6 = 0x6,
62//!    X7 = 0x7,
63//!    X8 = 0x8,
64//!    X9 = 0x9,
65//!    XA = 0xa,
66//!    XB = 0xb,
67//!}
68//!```
69//!
70//!Types U7 and U8, U9 to U16 and U16 through U32 are wrappers around u8, u16 and u32 respectively:
71//!
72//!```
73//!pub struct U20(u16);
74//!```
75//!
76//!Unfortunately there is no literal representation of these values, so they must be
77//!constructed using `From<T>` conversions or the `unchecked_from_xxx` functions
78//!
79//!## Traits
80//!
81//!The following traits are currently supported for all types:
82//!
83//!- `Debug for T`
84//!- `Display for T`
85//!- `LowerHex for T`
86//!- `From<u8> for T`
87//!- `From<T> for u8`
88//!- `From<u16> for T`
89//!- `From<T> for u16`
90//!- `From<u32> for T`
91//!- `From<T> for u32`
92//!- `From<usize> for T`
93//!- `From<T> for usize`
94//!- `From<i32> for T`
95//!- `From<T> for i32`
96//!- `PartialEq<i32> for T`
97//!
98//!The following additional traits are also supported for U1:
99//!
100//!- `From<bool> for U1`
101//!- `Not for U1`
102//!
103//!## Examples
104//!
105//!Here's an example using the U4 bit field type:
106//!
107//!```
108//!use bobbin_bits::*;
109//!
110//!// Implemented using a single exhaustive match statement
111//!fn to_hex_char<V: Into<U4>>(v: V) -> char {
112//!    let v = v.into();
113//!    match v {
114//!        U4::B0000 => '0',
115//!        U4::B0001 => '1',
116//!        U4::B0010 => '2',
117//!        U4::B0011 => '3',
118//!        U4::B0100 => '4',
119//!        U4::B0101 => '5',
120//!        U4::B0110 => '6',
121//!        U4::B0111 => '7',
122//!        U4::B1000 => '8',
123//!        U4::B1001 => '9',
124//!        U4::B1010 => 'a',
125//!        U4::B1011 => 'b',
126//!        U4::B1100 => 'c',
127//!        U4::B1101 => 'd',
128//!        U4::B1110 => 'e',
129//!        U4::B1111 => 'f',
130//!    }
131//!}
132//!
133//!// Call with a U4 bit field, no conversion or range checking is required.
134//!let c = to_hex_char(U4::B1000);
135//!assert_eq!(c, '8');
136//!
137//!// Call with a i32, v.into() performs range check.
138//!let c = to_hex_char(8);
139//!assert_eq!(c, '8');
140//!
141//!// Call with a u8, v.into() performs range check.
142//!let c = to_hex_char(8_u8);
143//!assert_eq!(c, '8');
144//!
145//!// Perform range check from u32 outside of function
146//!let v: U4 = 8u32.into();
147//!let c = to_hex_char(v);
148//!assert_eq!(c, '8');
149//!
150//!// A function that will extract bits [4:7] from a u32 value
151//!// without range checking
152//!fn extract_u4(v: u32) -> U4 {
153//!    unsafe {
154//!        U4::from_u32_unchecked(v >> 4 & 0b1111)
155//!    }
156//!}
157//!
158//!// No range checking needs to take place if a U4 is used
159//!// through the computation
160//!let c = to_hex_char(extract_u4(0b0000_0000_1000_0000));
161//!assert_eq!(c, '8');
162//!
163//!```
164//!
165//!Using the U12 and U13 types:
166//!
167//!```
168//!use bobbin_bits::*;
169//!
170//!fn double_sample<V: Into<U12>>(v: V) -> U13 {
171//!    let v = v.into();
172//!    // Extracts into u16, multiplies, then wraps into U13
173//!    // Performs range checking when creating the U13 value
174//!    U13::from(v.value() * 2)
175//!}
176//!
177//!// Range checking takes place within double_sample()
178//!let v = double_sample(1000);
179//!
180//!// Unfortunately, no literal form for U13, so range checking
181//!// happens when constructing U13 value from u16
182//!assert_eq!(v, U13::from(2000));
183//!
184//!// When converting from types that cannot overflow the range (such as u8),
185//!// no range checking is needed.
186//!assert_eq!(double_sample(100), U13::from(200u8));
187//!
188//!// You can always access the underlying representation of the value
189//!assert_eq!(v.value(), 2000u16);
190//!
191//!```
192//!
193//!Using the R4 range type, which supports values 0 to 3:
194//!
195//!```
196//!use bobbin_bits::*;
197//!
198//!// Using R4 in an exhaustive match
199//!fn get_port_name<I: Into<R4>>(index: I) -> &'static str {
200//!    let index = index.into();
201//!    match index {
202//!        R4::X0 => "PORTA",
203//!        R4::X1 => "PORTB",
204//!        R4::X2 => "PORTC",
205//!        R4::X3 => "PORTD",
206//!    }
207//!}
208//!
209//!pub const PORT_ADDR: [u32;4] = [0x1000_0000, 0x1000_2000, 0x1000_3000, 0x1000_4000];
210//!
211//!// Using a lookup table
212//!fn get_port_address<I: Into<R4>>(index: I) -> u32 {
213//!    // Is the optimizing compiler smart enough to eliminate the
214//!    // bounds check here?
215//!    PORT_ADDR[index.into() as usize]
216//!}
217//!
218//!// From<i32> is implemented, range check happens in get_port_name()
219//!let n = get_port_name(2);
220//!assert_eq!(n, "PORTC");
221//!
222//!// Using R4::X2 does not need a range check
223//!let n = get_port_name(R4::X2);
224//!assert_eq!(n, "PORTC");
225//!```
226
227#[cfg(test)]
228#[macro_use] extern crate std;
229
230use core::fmt;
231use core::mem::transmute;
232use core::ops::Not;
233
234#[macro_use] mod enums;
235#[macro_use] mod structs;
236#[macro_use] mod ranges;
237
238// Generate enums from U1 to U6
239
240impl_enum!(U1, 1, 0b1, 
241    B0 = 0b0, 
242    B1 = 0b1,
243);
244
245impl_enum!(U2, 2, 0b11, 
246    B00 = 0b00,
247    B01 = 0b01,
248    B10 = 0b10,
249    B11 = 0b11,
250);
251
252impl_enum!(U3, 3, 0b111, 
253    B000 = 0b000,
254    B001 = 0b001,
255    B010 = 0b010,
256    B011 = 0b011,
257    B100 = 0b100,
258    B101 = 0b101,
259    B110 = 0b110,
260    B111 = 0b111,
261);
262
263impl_enum!(U4, 4, 0b1111,
264    B0000 = 0b0000,
265    B0001 = 0b0001,
266    B0010 = 0b0010,
267    B0011 = 0b0011,
268    B0100 = 0b0100,
269    B0101 = 0b0101,
270    B0110 = 0b0110,
271    B0111 = 0b0111,
272    B1000 = 0b1000,
273    B1001 = 0b1001,
274    B1010 = 0b1010,
275    B1011 = 0b1011,
276    B1100 = 0b1100,
277    B1101 = 0b1101,
278    B1110 = 0b1110,
279    B1111 = 0b1111,
280);
281
282impl_enum!(U5, 5, 0b11111,
283    B00000 = 0b00000,
284    B00001 = 0b00001,
285    B00010 = 0b00010,
286    B00011 = 0b00011,
287    B00100 = 0b00100,
288    B00101 = 0b00101,
289    B00110 = 0b00110,
290    B00111 = 0b00111,
291    B01000 = 0b01000,
292    B01001 = 0b01001,
293    B01010 = 0b01010,
294    B01011 = 0b01011,
295    B01100 = 0b01100,
296    B01101 = 0b01101,
297    B01110 = 0b01110,
298    B01111 = 0b01111,
299    B10000 = 0b10000,
300    B10001 = 0b10001,
301    B10010 = 0b10010,
302    B10011 = 0b10011,
303    B10100 = 0b10100,
304    B10101 = 0b10101,
305    B10110 = 0b10110,
306    B10111 = 0b10111,
307    B11000 = 0b11000,
308    B11001 = 0b11001,
309    B11010 = 0b11010,
310    B11011 = 0b11011,
311    B11100 = 0b11100,
312    B11101 = 0b11101,
313    B11110 = 0b11110,
314    B11111 = 0b11111,
315);
316
317impl_enum!(U6, 6, 0b111111,
318    B000000 = 0b000000,
319    B000001 = 0b000001,
320    B000010 = 0b000010,
321    B000011 = 0b000011,
322    B000100 = 0b000100,
323    B000101 = 0b000101,
324    B000110 = 0b000110,
325    B000111 = 0b000111,
326    B001000 = 0b001000,
327    B001001 = 0b001001,
328    B001010 = 0b001010,
329    B001011 = 0b001011,
330    B001100 = 0b001100,
331    B001101 = 0b001101,
332    B001110 = 0b001110,
333    B001111 = 0b001111,
334    B010000 = 0b010000,
335    B010001 = 0b010001,
336    B010010 = 0b010010,
337    B010011 = 0b010011,
338    B010100 = 0b010100,
339    B010101 = 0b010101,
340    B010110 = 0b010110,
341    B010111 = 0b010111,
342    B011000 = 0b011000,
343    B011001 = 0b011001,
344    B011010 = 0b011010,
345    B011011 = 0b011011,
346    B011100 = 0b011100,
347    B011101 = 0b011101,
348    B011110 = 0b011110,
349    B011111 = 0b011111,
350    B100000 = 0b100000,
351    B100001 = 0b100001,
352    B100010 = 0b100010,
353    B100011 = 0b100011,
354    B100100 = 0b100100,
355    B100101 = 0b100101,
356    B100110 = 0b100110,
357    B100111 = 0b100111,
358    B101000 = 0b101000,
359    B101001 = 0b101001,
360    B101010 = 0b101010,
361    B101011 = 0b101011,
362    B101100 = 0b101100,
363    B101101 = 0b101101,
364    B101110 = 0b101110,
365    B101111 = 0b101111,
366    B110000 = 0b110000,
367    B110001 = 0b110001,
368    B110010 = 0b110010,
369    B110011 = 0b110011,
370    B110100 = 0b110100,
371    B110101 = 0b110101,
372    B110110 = 0b110110,
373    B110111 = 0b110111,
374    B111000 = 0b111000,
375    B111001 = 0b111001,
376    B111010 = 0b111010,
377    B111011 = 0b111011,
378    B111100 = 0b111100,
379    B111101 = 0b111101,
380    B111110 = 0b111110,
381    B111111 = 0b111111,
382);
383
384// Generate structs from U7 to U32
385
386impl_u8!(U7, 0b111_1111);
387impl_u8!(U8, 0b1111_11111);
388impl_u16!(U9, 0b1_1111_1111);
389impl_u16!(U10, 0b11_1111_1111);
390impl_u16!(U11, 0b111_1111_1111);
391impl_u16!(U12, 0b1111_1111_1111);
392impl_u16!(U13, 0b1_1111_1111_1111);
393impl_u16!(U14, 0b11_1111_1111_1111);
394impl_u16!(U15, 0b111_1111_1111_1111);
395impl_u16!(U16, 0b1111_1111_1111_1111);
396impl_u32!(U17, 0b1_1111_1111_1111_1111);
397impl_u32!(U18, 0b11_1111_1111_1111_1111);
398impl_u32!(U19, 0b111_1111_1111_1111_1111);
399impl_u32!(U20, 0b1111_1111_1111_1111_1111);
400impl_u32!(U21, 0b1_1111_1111_1111_1111_1111);
401impl_u32!(U22, 0b11_1111_1111_1111_1111_1111);
402impl_u32!(U23, 0b111_1111_1111_1111_1111_1111);
403impl_u32!(U24, 0b1111_1111_1111_1111_1111_1111);
404impl_u32!(U25, 0b1_1111_1111_1111_1111_1111_1111);
405impl_u32!(U26, 0b11_1111_1111_1111_1111_1111_1111);
406impl_u32!(U27, 0b111_1111_1111_1111_1111_1111_1111);
407impl_u32!(U28, 0b1111_1111_1111_1111_1111_1111_1111);
408impl_u32!(U29, 0b1_1111_1111_1111_1111_1111_1111_1111);
409impl_u32!(U30, 0b11_1111_1111_1111_1111_1111_1111_1111);
410impl_u32!(U31, 0b111_1111_1111_1111_1111_1111_1111_1111);
411impl_u32!(U32, 0b1111_1111_1111_1111_1111_1111_1111_1111);
412
413// Generate ranges from R1 to R32
414
415impl_range!(R1, 1,
416    X0 = 0x0,
417);
418
419impl_range!(R2, 2,
420    X0 = 0x0,
421    X1 = 0x1,
422);
423
424impl_range_from!(R2, R1);
425
426impl_range!(R3, 3,
427    X0 = 0x0,
428    X1 = 0x1,
429    X2 = 0x2,
430);
431
432impl_range_from!(R3, R2, R1);
433
434impl_range!(R4, 4,
435    X0 = 0x0,
436    X1 = 0x1,
437    X2 = 0x2,
438    X3 = 0x3,
439);
440
441impl_range_from!(R4, R3, R2, R1);
442
443impl_range!(R5, 5,
444    X0 = 0x0,
445    X1 = 0x1,
446    X2 = 0x2,
447    X3 = 0x3,
448    X4 = 0x4,
449);
450
451impl_range_from!(R5, R4, R3, R2, R1);
452
453impl_range!(R6, 6,
454    X0 = 0x0,
455    X1 = 0x1,
456    X2 = 0x2,
457    X3 = 0x3,
458    X4 = 0x4,
459    X5 = 0x5,
460    X6 = 0x6,
461);
462
463impl_range_from!(R6, R5, R4, R3, R2, R1);
464
465impl_range!(R7, 7,
466    X0 = 0x0,
467    X1 = 0x1,
468    X2 = 0x2,
469    X3 = 0x3,
470    X4 = 0x4,
471    X5 = 0x5,
472    X6 = 0x6,
473);
474
475impl_range_from!(R7, R5, R4, R3, R2, R1);
476
477impl_range!(R8, 8,
478    X0 = 0x0,
479    X1 = 0x1,
480    X2 = 0x2,
481    X3 = 0x3,
482    X4 = 0x4,
483    X5 = 0x5,
484    X6 = 0x6,
485    X7 = 0x7,
486);
487
488impl_range_from!(R8, R7, R5, R4, R3, R2, R1);
489
490impl_range!(R9, 9,
491    X0 = 0x0,
492    X1 = 0x1,
493    X2 = 0x2,
494    X3 = 0x3,
495    X4 = 0x4,
496    X5 = 0x5,
497    X6 = 0x6,
498    X7 = 0x7,
499    X8 = 0x8,
500);
501
502impl_range_from!(R9, R8, R7, R5, R4, R3, R2, R1);
503
504impl_range!(R10, 10,
505    X0 = 0x0,
506    X1 = 0x1,
507    X2 = 0x2,
508    X3 = 0x3,
509    X4 = 0x4,
510    X5 = 0x5,
511    X6 = 0x6,
512    X7 = 0x7,
513    X8 = 0x8,
514    X9 = 0x9,
515);
516
517impl_range_from!(R10, R9, R8, R7, R5, R4, R3, R2, R1);
518
519impl_range!(R11, 11,
520    X0 = 0x0,
521    X1 = 0x1,
522    X2 = 0x2,
523    X3 = 0x3,
524    X4 = 0x4,
525    X5 = 0x5,
526    X6 = 0x6,
527    X7 = 0x7,
528    X8 = 0x8,
529    X9 = 0x9,
530    Xa = 0xa,
531);
532
533impl_range_from!(R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
534
535impl_range!(R12, 12,
536    X0 = 0x0,
537    X1 = 0x1,
538    X2 = 0x2,
539    X3 = 0x3,
540    X4 = 0x4,
541    X5 = 0x5,
542    X6 = 0x6,
543    X7 = 0x7,
544    X8 = 0x8,
545    X9 = 0x9,
546    Xa = 0xa,
547    Xb = 0xb,
548);
549
550impl_range_from!(R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
551
552impl_range!(R13, 13,
553    X0 = 0x0,
554    X1 = 0x1,
555    X2 = 0x2,
556    X3 = 0x3,
557    X4 = 0x4,
558    X5 = 0x5,
559    X6 = 0x6,
560    X7 = 0x7,
561    X8 = 0x8,
562    X9 = 0x9,
563    Xa = 0xa,
564    Xb = 0xb,
565    Xc = 0xc,
566);
567
568impl_range_from!(R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
569
570impl_range!(R14, 14,
571    X0 = 0x0,
572    X1 = 0x1,
573    X2 = 0x2,
574    X3 = 0x3,
575    X4 = 0x4,
576    X5 = 0x5,
577    X6 = 0x6,
578    X7 = 0x7,
579    X8 = 0x8,
580    X9 = 0x9,
581    Xa = 0xa,
582    Xb = 0xb,
583    Xc = 0xc,
584    Xd = 0xd,
585);
586
587impl_range_from!(R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
588
589impl_range!(R15, 15,
590    X0 = 0x0,
591    X1 = 0x1,
592    X2 = 0x2,
593    X3 = 0x3,
594    X4 = 0x4,
595    X5 = 0x5,
596    X6 = 0x6,
597    X7 = 0x7,
598    X8 = 0x8,
599    X9 = 0x9,
600    Xa = 0xa,
601    Xb = 0xb,
602    Xc = 0xc,
603    Xd = 0xd,
604    Xe = 0xe,
605);
606
607impl_range_from!(R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
608
609impl_range!(R16, 16,
610    X0 = 0x0,
611    X1 = 0x1,
612    X2 = 0x2,
613    X3 = 0x3,
614    X4 = 0x4,
615    X5 = 0x5,
616    X6 = 0x6,
617    X7 = 0x7,
618    X8 = 0x8,
619    X9 = 0x9,
620    Xa = 0xa,
621    Xb = 0xb,
622    Xc = 0xc,
623    Xd = 0xd,
624    Xe = 0xe,
625    Xf = 0xf,
626);
627
628impl_range_from!(R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
629
630impl_range!(R17, 17,
631    X00 = 0x00,
632    X01 = 0x01,
633    X02 = 0x02,
634    X03 = 0x03,
635    X04 = 0x04,
636    X05 = 0x05,
637    X06 = 0x06,
638    X07 = 0x07,
639    X08 = 0x08,
640    X09 = 0x09,
641    X0a = 0x0a,
642    X0b = 0x0b,
643    X0c = 0x0c,
644    X0d = 0x0d,
645    X0e = 0x0e,
646    X0f = 0x0f,
647    X10 = 0x10,
648);
649
650impl_range_from!(R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
651
652impl_range!(R18, 18,
653    X00 = 0x00,
654    X01 = 0x01,
655    X02 = 0x02,
656    X03 = 0x03,
657    X04 = 0x04,
658    X05 = 0x05,
659    X06 = 0x06,
660    X07 = 0x07,
661    X08 = 0x08,
662    X09 = 0x09,
663    X0a = 0x0a,
664    X0b = 0x0b,
665    X0c = 0x0c,
666    X0d = 0x0d,
667    X0e = 0x0e,
668    X0f = 0x0f,
669    X10 = 0x10,
670    X11 = 0x11,
671);
672
673impl_range_from!(R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
674
675impl_range!(R19, 19,
676    X00 = 0x00,
677    X01 = 0x01,
678    X02 = 0x02,
679    X03 = 0x03,
680    X04 = 0x04,
681    X05 = 0x05,
682    X06 = 0x06,
683    X07 = 0x07,
684    X08 = 0x08,
685    X09 = 0x09,
686    X0a = 0x0a,
687    X0b = 0x0b,
688    X0c = 0x0c,
689    X0d = 0x0d,
690    X0e = 0x0e,
691    X0f = 0x0f,
692    X10 = 0x10,
693    X11 = 0x11,
694    X12 = 0x12,
695);
696
697impl_range_from!(R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
698
699impl_range!(R20, 20,
700    X00 = 0x00,
701    X01 = 0x01,
702    X02 = 0x02,
703    X03 = 0x03,
704    X04 = 0x04,
705    X05 = 0x05,
706    X06 = 0x06,
707    X07 = 0x07,
708    X08 = 0x08,
709    X09 = 0x09,
710    X0a = 0x0a,
711    X0b = 0x0b,
712    X0c = 0x0c,
713    X0d = 0x0d,
714    X0e = 0x0e,
715    X0f = 0x0f,
716    X10 = 0x10,
717    X11 = 0x11,
718    X12 = 0x12,
719    X13 = 0x13,
720);
721
722impl_range_from!(R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
723
724impl_range!(R21, 21,
725    X00 = 0x00,
726    X01 = 0x01,
727    X02 = 0x02,
728    X03 = 0x03,
729    X04 = 0x04,
730    X05 = 0x05,
731    X06 = 0x06,
732    X07 = 0x07,
733    X08 = 0x08,
734    X09 = 0x09,
735    X0a = 0x0a,
736    X0b = 0x0b,
737    X0c = 0x0c,
738    X0d = 0x0d,
739    X0e = 0x0e,
740    X0f = 0x0f,
741    X10 = 0x10,
742    X11 = 0x11,
743    X12 = 0x12,
744    X13 = 0x13,
745    X14 = 0x14,
746);
747
748impl_range_from!(R21, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
749
750impl_range!(R22, 22,
751    X00 = 0x00,
752    X01 = 0x01,
753    X02 = 0x02,
754    X03 = 0x03,
755    X04 = 0x04,
756    X05 = 0x05,
757    X06 = 0x06,
758    X07 = 0x07,
759    X08 = 0x08,
760    X09 = 0x09,
761    X0a = 0x0a,
762    X0b = 0x0b,
763    X0c = 0x0c,
764    X0d = 0x0d,
765    X0e = 0x0e,
766    X0f = 0x0f,
767    X10 = 0x10,
768    X11 = 0x11,
769    X12 = 0x12,
770    X13 = 0x13,
771    X14 = 0x14,
772    X15 = 0x15,
773);
774
775impl_range_from!(R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
776
777impl_range!(R23, 23,
778    X00 = 0x00,
779    X01 = 0x01,
780    X02 = 0x02,
781    X03 = 0x03,
782    X04 = 0x04,
783    X05 = 0x05,
784    X06 = 0x06,
785    X07 = 0x07,
786    X08 = 0x08,
787    X09 = 0x09,
788    X0a = 0x0a,
789    X0b = 0x0b,
790    X0c = 0x0c,
791    X0d = 0x0d,
792    X0e = 0x0e,
793    X0f = 0x0f,
794    X10 = 0x10,
795    X11 = 0x11,
796    X12 = 0x12,
797    X13 = 0x13,
798    X14 = 0x14,
799    X15 = 0x15,
800    X16 = 0x16,
801);
802
803impl_range_from!(R23, R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
804
805impl_range!(R24, 24,
806    X00 = 0x00,
807    X01 = 0x01,
808    X02 = 0x02,
809    X03 = 0x03,
810    X04 = 0x04,
811    X05 = 0x05,
812    X06 = 0x06,
813    X07 = 0x07,
814    X08 = 0x08,
815    X09 = 0x09,
816    X0a = 0x0a,
817    X0b = 0x0b,
818    X0c = 0x0c,
819    X0d = 0x0d,
820    X0e = 0x0e,
821    X0f = 0x0f,
822    X10 = 0x10,
823    X11 = 0x11,
824    X12 = 0x12,
825    X13 = 0x13,
826    X14 = 0x14,
827    X15 = 0x15,
828    X16 = 0x16,
829    X17 = 0x17,
830);
831
832impl_range_from!(R24, R23, R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
833
834impl_range!(R25, 25,
835    X00 = 0x00,
836    X01 = 0x01,
837    X02 = 0x02,
838    X03 = 0x03,
839    X04 = 0x04,
840    X05 = 0x05,
841    X06 = 0x06,
842    X07 = 0x07,
843    X08 = 0x08,
844    X09 = 0x09,
845    X0a = 0x0a,
846    X0b = 0x0b,
847    X0c = 0x0c,
848    X0d = 0x0d,
849    X0e = 0x0e,
850    X0f = 0x0f,
851    X10 = 0x10,
852    X11 = 0x11,
853    X12 = 0x12,
854    X13 = 0x13,
855    X14 = 0x14,
856    X15 = 0x15,
857    X16 = 0x16,
858    X17 = 0x17,
859    X18 = 0x18,
860);
861
862impl_range_from!(R25, R24, R23, R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
863
864impl_range!(R26, 26,
865    X00 = 0x00,
866    X01 = 0x01,
867    X02 = 0x02,
868    X03 = 0x03,
869    X04 = 0x04,
870    X05 = 0x05,
871    X06 = 0x06,
872    X07 = 0x07,
873    X08 = 0x08,
874    X09 = 0x09,
875    X0a = 0x0a,
876    X0b = 0x0b,
877    X0c = 0x0c,
878    X0d = 0x0d,
879    X0e = 0x0e,
880    X0f = 0x0f,
881    X10 = 0x10,
882    X11 = 0x11,
883    X12 = 0x12,
884    X13 = 0x13,
885    X14 = 0x14,
886    X15 = 0x15,
887    X16 = 0x16,
888    X17 = 0x17,
889    X18 = 0x18,
890    X19 = 0x19,
891);
892
893impl_range_from!(R26, R25, R24, R23, R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
894
895impl_range!(R27, 27,
896    X00 = 0x00,
897    X01 = 0x01,
898    X02 = 0x02,
899    X03 = 0x03,
900    X04 = 0x04,
901    X05 = 0x05,
902    X06 = 0x06,
903    X07 = 0x07,
904    X08 = 0x08,
905    X09 = 0x09,
906    X0a = 0x0a,
907    X0b = 0x0b,
908    X0c = 0x0c,
909    X0d = 0x0d,
910    X0e = 0x0e,
911    X0f = 0x0f,
912    X10 = 0x10,
913    X11 = 0x11,
914    X12 = 0x12,
915    X13 = 0x13,
916    X14 = 0x14,
917    X15 = 0x15,
918    X16 = 0x16,
919    X17 = 0x17,
920    X18 = 0x18,
921    X19 = 0x19,
922    X1a = 0x1a,
923);
924
925impl_range_from!(R27, R26, R25, R24, R23, R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
926
927impl_range!(R28, 28,
928    X00 = 0x00,
929    X01 = 0x01,
930    X02 = 0x02,
931    X03 = 0x03,
932    X04 = 0x04,
933    X05 = 0x05,
934    X06 = 0x06,
935    X07 = 0x07,
936    X08 = 0x08,
937    X09 = 0x09,
938    X0a = 0x0a,
939    X0b = 0x0b,
940    X0c = 0x0c,
941    X0d = 0x0d,
942    X0e = 0x0e,
943    X0f = 0x0f,
944    X10 = 0x10,
945    X11 = 0x11,
946    X12 = 0x12,
947    X13 = 0x13,
948    X14 = 0x14,
949    X15 = 0x15,
950    X16 = 0x16,
951    X17 = 0x17,
952    X18 = 0x18,
953    X19 = 0x19,
954    X1a = 0x1a,
955    X1b = 0x1b,
956);
957
958impl_range_from!(R28, R27, R26, R25, R24, R23, R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
959
960impl_range!(R29, 29,
961    X00 = 0x00,
962    X01 = 0x01,
963    X02 = 0x02,
964    X03 = 0x03,
965    X04 = 0x04,
966    X05 = 0x05,
967    X06 = 0x06,
968    X07 = 0x07,
969    X08 = 0x08,
970    X09 = 0x09,
971    X0a = 0x0a,
972    X0b = 0x0b,
973    X0c = 0x0c,
974    X0d = 0x0d,
975    X0e = 0x0e,
976    X0f = 0x0f,
977    X10 = 0x10,
978    X11 = 0x11,
979    X12 = 0x12,
980    X13 = 0x13,
981    X14 = 0x14,
982    X15 = 0x15,
983    X16 = 0x16,
984    X17 = 0x17,
985    X18 = 0x18,
986    X19 = 0x19,
987    X1a = 0x1a,
988    X1b = 0x1b,
989    X1c = 0x1c,
990);
991
992impl_range_from!(R29, R28, R27, R26, R25, R24, R23, R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
993
994impl_range!(R30, 30,
995    X00 = 0x00,
996    X01 = 0x01,
997    X02 = 0x02,
998    X03 = 0x03,
999    X04 = 0x04,
1000    X05 = 0x05,
1001    X06 = 0x06,
1002    X07 = 0x07,
1003    X08 = 0x08,
1004    X09 = 0x09,
1005    X0a = 0x0a,
1006    X0b = 0x0b,
1007    X0c = 0x0c,
1008    X0d = 0x0d,
1009    X0e = 0x0e,
1010    X0f = 0x0f,
1011    X10 = 0x10,
1012    X11 = 0x11,
1013    X12 = 0x12,
1014    X13 = 0x13,
1015    X14 = 0x14,
1016    X15 = 0x15,
1017    X16 = 0x16,
1018    X17 = 0x17,
1019    X18 = 0x18,
1020    X19 = 0x19,
1021    X1a = 0x1a,
1022    X1b = 0x1b,
1023    X1c = 0x1c,
1024    X1d = 0x1d,
1025);
1026
1027impl_range_from!(R30, R29, R28, R27, R26, R25, R24, R23, R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
1028
1029impl_range!(R31, 31,
1030    X00 = 0x00,
1031    X01 = 0x01,
1032    X02 = 0x02,
1033    X03 = 0x03,
1034    X04 = 0x04,
1035    X05 = 0x05,
1036    X06 = 0x06,
1037    X07 = 0x07,
1038    X08 = 0x08,
1039    X09 = 0x09,
1040    X0a = 0x0a,
1041    X0b = 0x0b,
1042    X0c = 0x0c,
1043    X0d = 0x0d,
1044    X0e = 0x0e,
1045    X0f = 0x0f,
1046    X10 = 0x10,
1047    X11 = 0x11,
1048    X12 = 0x12,
1049    X13 = 0x13,
1050    X14 = 0x14,
1051    X15 = 0x15,
1052    X16 = 0x16,
1053    X17 = 0x17,
1054    X18 = 0x18,
1055    X19 = 0x19,
1056    X1a = 0x1a,
1057    X1b = 0x1b,
1058    X1c = 0x1c,
1059    X1d = 0x1d,
1060    X1e = 0x1e,
1061);
1062
1063impl_range_from!(R31, R30, R29, R28, R27, R26, R25, R24, R23, R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
1064
1065impl_range!(R32, 32,
1066    X00 = 0x00,
1067    X01 = 0x01,
1068    X02 = 0x02,
1069    X03 = 0x03,
1070    X04 = 0x04,
1071    X05 = 0x05,
1072    X06 = 0x06,
1073    X07 = 0x07,
1074    X08 = 0x08,
1075    X09 = 0x09,
1076    X0a = 0x0a,
1077    X0b = 0x0b,
1078    X0c = 0x0c,
1079    X0d = 0x0d,
1080    X0e = 0x0e,
1081    X0f = 0x0f,
1082    X10 = 0x10,
1083    X11 = 0x11,
1084    X12 = 0x12,
1085    X13 = 0x13,
1086    X14 = 0x14,
1087    X15 = 0x15,
1088    X16 = 0x16,
1089    X17 = 0x17,
1090    X18 = 0x18,
1091    X19 = 0x19,
1092    X1a = 0x1a,
1093    X1b = 0x1b,
1094    X1c = 0x1c,
1095    X1d = 0x1d,
1096    X1e = 0x1e,
1097    X1f = 0x1f,
1098);
1099
1100impl_range_from!(R32, R31, R30, R29, R28, R27, R26, R25, R24, R23, R22, R20, R19, R18, R17, R16, R15, R14, R13, R12, R11, R10, R9, R8, R7, R5, R4, R3, R2, R1);
1101
1102
1103// Special Traits for U1
1104
1105
1106impl From<bool> for U1 {
1107    #[inline]
1108    fn from(other: bool) -> U1 {
1109        U1::from(other as u8)
1110    }
1111}
1112
1113impl U1 {
1114    #[inline]
1115    pub fn is_set(&self) -> bool {
1116        *self as u8 != 0
1117    }
1118}
1119
1120impl Not for U1 {
1121    type Output = U1;
1122    #[inline]
1123    fn not(self) -> U1 {
1124        U1::from(self as u8)
1125    }
1126}
1127
1128
1129#[cfg(test)]
1130mod tests {
1131    use super::*;
1132
1133    #[test]
1134    fn it_works() {
1135        assert_eq!(U1::from(0), U1::B0);
1136        assert_eq!(U1::from(1), U1::B1);
1137        let v: u8 = U1::B0.into();
1138        assert_eq!(v, 0u8);
1139        assert_eq!(<U1 as Into<u8>>::into(U1::B1), 1u8);
1140
1141        // let value: u32 = U1::B1.into();
1142    }
1143    #[test]
1144    fn test_bool_cast() {
1145        assert_eq!(true as u32, 1);
1146        assert_eq!(false as u32, 0);
1147        assert_eq!(0 != 0, false);
1148        assert_eq!(1 != 0, true);
1149    }
1150
1151    #[test]
1152    fn test_fn_into() {
1153        fn abc<V: Into<U2>>(v: V) -> U2 {
1154            v.into()
1155        }
1156        assert_eq!(abc(0b00u8), U2::B00);
1157        assert_eq!(abc(0b11u8), U2::B11);
1158
1159        fn def<V: Into<u8>>(v: V) -> u8 {
1160            v.into()
1161        }
1162
1163        assert_eq!(def(U2::B01), 0b01u8);
1164        assert_eq!(def(0b01u8), 0b01u8);
1165
1166        assert_eq!(U1::B0, U1::from(false));
1167        assert_eq!(U1::B1, U1::from(true));
1168    }
1169
1170    #[test]
1171    fn test_b1() {
1172        let f = U1::B0;
1173        let t = U1::B1;
1174
1175        assert!(t.is_set());
1176        assert!(!f.is_set());
1177
1178        assert!(t.value() != 0);
1179        assert!(f.value() == 0);
1180
1181        assert!(t == 1);
1182        assert!(f == 0);
1183    }
1184
1185    #[test]
1186    fn test_b16() {
1187        fn use_b16<V: Into<U16>>(v: V) -> U16 {
1188            v.into()
1189        }
1190        fn use_u16(v: u16) -> u16 {
1191            v
1192        }
1193
1194        let x: U16 = U16::from(0);
1195        assert_eq!(x.value(), 0);
1196
1197        let x: U16 = U16::from(0b1111);
1198        assert_eq!(use_b16(x), x);
1199        assert_eq!(use_b16(0b1111), x);
1200
1201        assert!(x == 0b1111);
1202        assert!(use_u16(x.into()) == 0b1111u16);
1203
1204        assert!(U16::from(8).value() < 9);
1205    }
1206
1207    // Ranges
1208
1209    #[test]
1210    fn test_r2() {
1211        let v0 = R2::X0;
1212        let v1 = R2::X1;
1213
1214        assert_eq!(v0, 0);
1215        assert_eq!(v1, 1);
1216
1217        assert_eq!(v0, 0u8);
1218        assert_eq!(v1, 1u8);
1219
1220        assert_eq!(v0, 0u16);
1221        assert_eq!(v1, 1u16);
1222
1223        assert_eq!(v0, 0u32);
1224        assert_eq!(v1, 1u32);
1225
1226        assert_eq!(v0, 0usize);
1227        assert_eq!(v1, 1usize);
1228
1229        assert_eq!(v0, R2::from(0));
1230        assert_eq!(v1, R2::from(1));
1231
1232        assert_eq!(v0, R2::from(0u8));
1233        assert_eq!(v1, R2::from(1u8));
1234
1235        assert_eq!(v0, R2::from(0u16));
1236        assert_eq!(v1, R2::from(1u16));
1237
1238        assert_eq!(v0, R2::from(0u32));
1239        assert_eq!(v1, R2::from(1u32));
1240
1241        assert_eq!(v0, R2::from(0usize));
1242        assert_eq!(v1, R2::from(1usize));
1243
1244        let x0: usize = v0.into();
1245        let x1: usize = v1.into();
1246        assert_eq!(x0, 0usize);
1247        assert_eq!(x1, 1usize);
1248    }
1249
1250    #[test]
1251    fn test_range_convert() {
1252        let r2 = R2::X1;
1253        let r3: R3 = r2.into();
1254        let r4: R4 = r3.into();
1255        assert_eq!(r2.value(), r3.value());
1256        assert_eq!(r2.value(), r4.value());
1257    }
1258
1259    #[test]
1260    fn test_debug() {
1261        assert_eq!(format!("{:?}",U1::from(0b1)),"0b1");
1262        assert_eq!(format!("{:?}",U2::from(0b11)),"0b11");
1263        assert_eq!(format!("{:?}",U3::from(0b111)),"0b111");
1264        assert_eq!(format!("{:?}",U4::from(0b1111)),"0b1111");
1265        assert_eq!(format!("{:?}",U5::from(0b11111)),"0b11111");
1266        assert_eq!(format!("{:?}",U6::from(0b111111)),"0b111111");
1267        assert_eq!(format!("{:?}",U8::from(0xffu16)),"0xff");
1268        assert_eq!(format!("{:?}",U12::from(0xfffu16)),"0xfff");
1269        assert_eq!(format!("{:?}",U16::from(0xffffu16)),"0xffff");
1270        assert_eq!(format!("{:?}",U20::from(0xfffffu32)),"0xfffff");
1271        assert_eq!(format!("{:?}",U24::from(0xffffffu32)),"0xffffff");
1272        assert_eq!(format!("{:?}",U28::from(0xfffffffu32)),"0xfffffff");
1273        assert_eq!(format!("{:?}",U32::from(0xffffffffu32)),"0xffffffff");
1274    }
1275
1276    #[test]
1277    fn test_display() {
1278        assert_eq!(format!("{}",U1::from(0b1)),"1");
1279        assert_eq!(format!("{}",U2::from(0b11)),"3");
1280        assert_eq!(format!("{}",U3::from(0b111)),"7");
1281        assert_eq!(format!("{}",U4::from(0b1111)),"15");
1282        assert_eq!(format!("{}",U5::from(0b11111)),"31");
1283        assert_eq!(format!("{}",U6::from(0b111111)),"63");
1284        assert_eq!(format!("{}",U8::from(0xffu16)),"255");
1285        assert_eq!(format!("{}",U12::from(0xfffu16)),"4095");
1286        assert_eq!(format!("{}",U16::from(0xffffu16)),"65535");
1287        assert_eq!(format!("{}",U20::from(0xfffffu32)),"1048575");
1288        assert_eq!(format!("{}",U24::from(0xffffffu32)),"16777215");
1289        assert_eq!(format!("{}",U28::from(0xfffffffu32)),"268435455");
1290        assert_eq!(format!("{}",U32::from(0xffffffffu32)),"4294967295");
1291    }
1292}