1use crate::{CtAssign, CtAssignSlice, CtEq, CtEqSlice, CtSelectUsingCtAssign};
2use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not};
3
4#[cfg(feature = "subtle")]
5use crate::CtSelect;
6
7macro_rules! bitle {
11 ($x:expr, $y:expr, $bits:expr) => {
12 (((!$x) | $y) & (($x ^ $y) | !($y.wrapping_sub($x)))) >> ($bits - 1)
13 };
14}
15
16macro_rules! bitlt {
20 ($x:expr, $y:expr, $bits:expr) => {
21 (((!$x) & $y) | (((!$x) | $y) & $x.wrapping_sub($y))) >> ($bits - 1)
22 };
23}
24
25macro_rules! bitnz {
27 ($value:expr, $bits:expr) => {
28 ($value | $value.wrapping_neg()) >> ($bits - 1)
29 };
30}
31
32#[derive(Copy, Clone, Debug)]
42pub struct Choice(pub(crate) u8);
43
44impl Choice {
45 pub const FALSE: Self = Self(0);
47
48 pub const TRUE: Self = Self(1);
50
51 #[inline]
57 #[must_use]
58 pub const fn and(self, rhs: Choice) -> Choice {
59 Self(self.0 & rhs.0)
60 }
61
62 #[inline]
64 #[must_use]
65 pub const fn or(self, rhs: Choice) -> Choice {
66 Self(self.0 | rhs.0)
67 }
68
69 #[inline]
71 #[must_use]
72 pub const fn xor(self, rhs: Choice) -> Choice {
73 Self(self.0 ^ rhs.0)
74 }
75
76 #[inline]
78 #[must_use]
79 pub const fn not(self) -> Choice {
80 Self(self.0 ^ 1)
82 }
83
84 #[inline]
90 #[must_use]
91 pub const fn eq(self, other: Self) -> Self {
92 Self::ne(self, other).not()
93 }
94
95 #[inline]
97 #[must_use]
98 pub const fn ne(self, other: Self) -> Self {
99 Self::xor(self, other)
100 }
101
102 #[inline]
110 #[must_use]
111 #[allow(clippy::cast_sign_loss)]
112 pub const fn from_i64_eq(x: i64, y: i64) -> Self {
113 Self::from_u64_nz(x as u64 ^ y as u64).not()
115 }
116
117 #[inline]
121 #[must_use]
122 pub const fn from_u8_eq(x: u8, y: u8) -> Self {
123 Self::from_u8_nz(x ^ y).not()
124 }
125
126 #[inline]
128 #[must_use]
129 pub const fn from_u8_le(x: u8, y: u8) -> Self {
130 Self::from_u8_lsb(bitle!(x, y, u8::BITS))
131 }
132
133 #[inline]
135 #[must_use]
136 pub const fn from_u8_lsb(value: u8) -> Self {
137 Self(value & 0x1)
138 }
139
140 #[inline]
142 #[must_use]
143 pub const fn from_u8_lt(x: u8, y: u8) -> Self {
144 Self::from_u8_lsb(bitlt!(x, y, u8::BITS))
145 }
146
147 #[inline]
149 #[must_use]
150 pub const fn from_u8_nz(value: u8) -> Self {
151 Self::from_u8_lsb(bitnz!(value, u8::BITS))
152 }
153
154 #[inline]
158 #[must_use]
159 pub const fn from_u16_eq(x: u16, y: u16) -> Self {
160 Self::from_u16_nz(x ^ y).not()
161 }
162
163 #[inline]
165 #[must_use]
166 pub const fn from_u16_le(x: u16, y: u16) -> Self {
167 Self::from_u16_lsb(bitle!(x, y, u16::BITS))
168 }
169
170 #[inline]
172 #[must_use]
173 pub const fn from_u16_lsb(value: u16) -> Self {
174 Self((value & 0x1) as u8)
175 }
176
177 #[inline]
179 #[must_use]
180 pub const fn from_u16_lt(x: u16, y: u16) -> Self {
181 Self::from_u16_lsb(bitlt!(x, y, u16::BITS))
182 }
183
184 #[inline]
186 #[must_use]
187 pub const fn from_u16_nz(value: u16) -> Self {
188 Self::from_u16_lsb(bitnz!(value, u16::BITS))
189 }
190
191 #[inline]
195 #[must_use]
196 pub const fn from_u32_eq(x: u32, y: u32) -> Self {
197 Self::from_u32_nz(x ^ y).not()
198 }
199
200 #[inline]
202 #[must_use]
203 pub const fn from_u32_le(x: u32, y: u32) -> Self {
204 Self::from_u32_lsb(bitle!(x, y, u32::BITS))
205 }
206
207 #[inline]
209 #[must_use]
210 pub const fn from_u32_lsb(value: u32) -> Self {
211 Self((value & 0x1) as u8)
212 }
213
214 #[inline]
216 #[must_use]
217 pub const fn from_u32_lt(x: u32, y: u32) -> Self {
218 Self::from_u32_lsb(bitlt!(x, y, u32::BITS))
219 }
220
221 #[inline]
223 #[must_use]
224 pub const fn from_u32_nz(value: u32) -> Self {
225 Self::from_u32_lsb(bitnz!(value, u32::BITS))
226 }
227
228 #[inline]
232 #[must_use]
233 pub const fn from_u64_eq(x: u64, y: u64) -> Self {
234 Self::from_u64_nz(x ^ y).not()
235 }
236
237 #[inline]
239 #[must_use]
240 pub const fn from_u64_le(x: u64, y: u64) -> Self {
241 Self::from_u64_lsb(bitle!(x, y, u64::BITS))
242 }
243
244 #[inline]
246 #[must_use]
247 pub const fn from_u64_lsb(value: u64) -> Self {
248 Self((value & 0x1) as u8)
249 }
250
251 #[inline]
253 #[must_use]
254 pub const fn from_u64_lt(x: u64, y: u64) -> Self {
255 Self::from_u64_lsb(bitlt!(x, y, u64::BITS))
256 }
257
258 #[inline]
260 #[must_use]
261 pub const fn from_u64_nz(value: u64) -> Self {
262 Self::from_u64_lsb(bitnz!(value, u64::BITS))
263 }
264
265 #[inline]
269 #[must_use]
270 pub const fn from_u128_eq(x: u128, y: u128) -> Self {
271 Self::from_u128_nz(x ^ y).not()
272 }
273
274 #[inline]
276 #[must_use]
277 pub const fn from_u128_le(x: u128, y: u128) -> Self {
278 Self::from_u128_lsb(bitle!(x, y, u128::BITS))
279 }
280
281 #[inline]
283 #[must_use]
284 pub const fn from_u128_lsb(value: u128) -> Self {
285 Self((value & 1) as u8)
286 }
287
288 #[inline]
290 #[must_use]
291 pub const fn from_u128_lt(x: u128, y: u128) -> Self {
292 Self::from_u128_lsb(bitlt!(x, y, u128::BITS))
293 }
294
295 #[inline]
297 #[must_use]
298 pub const fn from_u128_nz(value: u128) -> Self {
299 Self::from_u128_lsb(bitnz!(value, u128::BITS))
300 }
301
302 #[inline]
311 #[must_use]
312 #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]
313 pub const fn select_i64(self, a: i64, b: i64) -> i64 {
314 self.select_u64(a as u64, b as u64) as i64
316 }
317
318 #[inline]
323 #[must_use]
324 pub const fn select_u8(self, a: u8, b: u8) -> u8 {
325 a ^ (self.to_u8_mask() & (a ^ b))
326 }
327
328 #[inline]
333 #[must_use]
334 pub const fn select_u16(self, a: u16, b: u16) -> u16 {
335 a ^ (self.to_u16_mask() & (a ^ b))
336 }
337
338 #[inline]
343 #[must_use]
344 pub const fn select_u32(self, a: u32, b: u32) -> u32 {
345 a ^ (self.to_u32_mask() & (a ^ b))
346 }
347
348 #[inline]
353 #[must_use]
354 pub const fn select_u64(self, a: u64, b: u64) -> u64 {
355 a ^ (self.to_u64_mask() & (a ^ b))
356 }
357
358 #[inline]
363 #[must_use]
364 pub const fn select_u128(self, a: u128, b: u128) -> u128 {
365 a ^ (self.to_u128_mask() & (a ^ b))
366 }
367
368 #[must_use]
391 pub fn to_bool(self) -> bool {
392 self.to_u8() != 0
393 }
394
395 #[must_use]
398 pub fn to_u8(self) -> u8 {
399 core::hint::black_box(self.0)
403 }
404
405 #[must_use]
416 pub const fn to_bool_vartime(self) -> bool {
417 self.0 != 0
418 }
419
420 #[must_use]
425 pub const fn to_u8_vartime(self) -> u8 {
426 self.0
427 }
428
429 #[inline]
435 #[must_use]
436 pub const fn to_u8_mask(self) -> u8 {
437 self.0.wrapping_neg()
438 }
439
440 #[inline]
446 #[must_use]
447 pub const fn to_u16_mask(self) -> u16 {
448 (self.0 as u16).wrapping_neg()
449 }
450
451 #[inline]
457 #[must_use]
458 pub const fn to_u32_mask(self) -> u32 {
459 (self.0 as u32).wrapping_neg()
460 }
461
462 #[inline]
468 #[must_use]
469 pub const fn to_u64_mask(self) -> u64 {
470 (self.0 as u64).wrapping_neg()
471 }
472
473 #[inline]
479 #[must_use]
480 pub const fn to_u128_mask(self) -> u128 {
481 (self.0 as u128).wrapping_neg()
482 }
483}
484
485impl BitAnd for Choice {
486 type Output = Choice;
487
488 #[inline]
489 fn bitand(self, rhs: Choice) -> Choice {
490 self.and(rhs)
491 }
492}
493
494impl BitAndAssign for Choice {
495 #[inline]
496 fn bitand_assign(&mut self, rhs: Choice) {
497 *self = *self & rhs;
498 }
499}
500
501impl BitOr for Choice {
502 type Output = Choice;
503
504 #[inline]
505 fn bitor(self, rhs: Choice) -> Choice {
506 self.or(rhs)
507 }
508}
509
510impl BitOrAssign for Choice {
511 #[inline]
512 fn bitor_assign(&mut self, rhs: Choice) {
513 *self = *self | rhs;
514 }
515}
516
517impl BitXor for Choice {
518 type Output = Choice;
519
520 #[inline]
521 fn bitxor(self, rhs: Choice) -> Choice {
522 Choice(self.0 ^ rhs.0)
523 }
524}
525
526impl BitXorAssign for Choice {
527 #[inline]
528 fn bitxor_assign(&mut self, rhs: Choice) {
529 *self = *self ^ rhs;
530 }
531}
532
533impl CtAssign for Choice {
534 #[inline]
535 fn ct_assign(&mut self, other: &Self, choice: Choice) {
536 self.0.ct_assign(&other.0, choice);
537 }
538}
539impl CtAssignSlice for Choice {}
540impl CtSelectUsingCtAssign for Choice {}
541
542impl CtEq for Choice {
543 #[inline]
544 fn ct_eq(&self, other: &Self) -> Self {
545 self.0.ct_eq(&other.0)
546 }
547}
548impl CtEqSlice for Choice {}
549
550impl From<u8> for Choice {
559 fn from(value: u8) -> Self {
560 Choice::from_u8_lsb(value)
561 }
562}
563
564impl From<Choice> for u8 {
565 fn from(choice: Choice) -> u8 {
566 choice.to_u8()
567 }
568}
569
570impl From<Choice> for bool {
581 fn from(choice: Choice) -> bool {
582 choice.to_bool()
583 }
584}
585
586impl Not for Choice {
587 type Output = Choice;
588
589 #[inline]
590 fn not(self) -> Choice {
591 self.not()
592 }
593}
594
595#[cfg(feature = "subtle")]
596impl From<subtle::Choice> for Choice {
597 #[inline]
598 fn from(choice: subtle::Choice) -> Choice {
599 Choice(choice.unwrap_u8())
600 }
601}
602
603#[cfg(feature = "subtle")]
604impl From<Choice> for subtle::Choice {
605 #[inline]
606 fn from(choice: Choice) -> subtle::Choice {
607 subtle::Choice::from(choice.0)
608 }
609}
610
611#[cfg(feature = "subtle")]
612impl subtle::ConditionallySelectable for Choice {
613 #[inline]
614 fn conditional_select(a: &Self, b: &Self, choice: subtle::Choice) -> Self {
615 CtSelect::ct_select(a, b, choice.into())
616 }
617}
618
619#[cfg(feature = "subtle")]
620impl subtle::ConstantTimeEq for Choice {
621 #[inline]
622 fn ct_eq(&self, other: &Self) -> subtle::Choice {
623 CtEq::ct_eq(self, other).into()
624 }
625}
626
627#[cfg(test)]
628mod tests {
629 use super::Choice;
630 use crate::{CtEq, CtSelect};
631
632 #[test]
633 fn ct_eq() {
634 let a = Choice::TRUE;
635 let b = Choice::TRUE;
636 let c = Choice::FALSE;
637
638 assert!(a.ct_eq(&b).to_bool());
639 assert!(!a.ct_eq(&c).to_bool());
640 assert!(!b.ct_eq(&c).to_bool());
641
642 assert!(!a.ct_ne(&b).to_bool());
643 assert!(a.ct_ne(&c).to_bool());
644 assert!(b.ct_ne(&c).to_bool());
645 }
646
647 #[test]
648 fn ct_select() {
649 let a = Choice::FALSE;
650 let b = Choice::TRUE;
651 assert_eq!(a.ct_select(&b, Choice::FALSE).to_bool(), a.to_bool());
652 assert_eq!(a.ct_select(&b, Choice::TRUE).to_bool(), b.to_bool());
653 }
654
655 #[test]
656 fn and() {
657 assert_eq!((Choice::FALSE & Choice::FALSE).to_u8(), 0);
658 assert_eq!((Choice::TRUE & Choice::FALSE).to_u8(), 0);
659 assert_eq!((Choice::FALSE & Choice::TRUE).to_u8(), 0);
660 assert_eq!((Choice::TRUE & Choice::TRUE).to_u8(), 1);
661 }
662
663 #[test]
664 fn or() {
665 assert_eq!((Choice::FALSE | Choice::FALSE).to_u8(), 0);
666 assert_eq!((Choice::TRUE | Choice::FALSE).to_u8(), 1);
667 assert_eq!((Choice::FALSE | Choice::TRUE).to_u8(), 1);
668 assert_eq!((Choice::TRUE | Choice::TRUE).to_u8(), 1);
669 }
670
671 #[test]
672 fn xor() {
673 assert_eq!((Choice::FALSE ^ Choice::FALSE).to_u8(), 0);
674 assert_eq!((Choice::TRUE ^ Choice::FALSE).to_u8(), 1);
675 assert_eq!((Choice::FALSE ^ Choice::TRUE).to_u8(), 1);
676 assert_eq!((Choice::TRUE ^ Choice::TRUE).to_u8(), 0);
677 }
678
679 #[test]
680 fn not() {
681 assert_eq!(Choice::FALSE.not().to_u8(), 1);
682 assert_eq!(Choice::TRUE.not().to_u8(), 0);
683 }
684
685 #[test]
686 fn from_i64_eq() {
687 assert!(Choice::from_i64_eq(0, 1).eq(Choice::FALSE).to_bool());
688 assert!(Choice::from_i64_eq(1, 1).eq(Choice::TRUE).to_bool());
689 }
690
691 #[test]
692 fn from_u8_eq() {
693 assert!(Choice::from_u8_eq(0, 1).eq(Choice::FALSE).to_bool());
694 assert!(Choice::from_u8_eq(1, 1).eq(Choice::TRUE).to_bool());
695 }
696
697 #[test]
698 fn from_u8_le() {
699 assert!(Choice::from_u8_le(0, 0).eq(Choice::TRUE).to_bool());
700 assert!(Choice::from_u8_le(1, 0).eq(Choice::FALSE).to_bool());
701 assert!(Choice::from_u8_le(1, 1).eq(Choice::TRUE).to_bool());
702 assert!(Choice::from_u8_le(1, 2).eq(Choice::TRUE).to_bool());
703 }
704
705 #[test]
706 fn from_u8_lsb() {
707 assert!(Choice::from_u8_lsb(0).eq(Choice::FALSE).to_bool());
708 assert!(Choice::from_u8_lsb(1).eq(Choice::TRUE).to_bool());
709 assert!(Choice::from_u8_lsb(2).eq(Choice::FALSE).to_bool());
710 assert!(Choice::from_u8_lsb(3).eq(Choice::TRUE).to_bool());
711 }
712
713 #[test]
714 fn from_u8_lt() {
715 assert!(Choice::from_u8_lt(0, 0).eq(Choice::FALSE).to_bool());
716 assert!(Choice::from_u8_lt(1, 0).eq(Choice::FALSE).to_bool());
717 assert!(Choice::from_u8_lt(1, 1).eq(Choice::FALSE).to_bool());
718 assert!(Choice::from_u8_lt(1, 2).eq(Choice::TRUE).to_bool());
719 }
720
721 #[test]
722 fn from_u8_nz() {
723 assert!(Choice::from_u8_nz(0).eq(Choice::FALSE).to_bool());
724 assert!(Choice::from_u8_nz(1).eq(Choice::TRUE).to_bool());
725 assert!(Choice::from_u8_nz(2).eq(Choice::TRUE).to_bool());
726 }
727
728 #[test]
729 fn from_u16_eq() {
730 assert!(Choice::from_u16_eq(0, 1).eq(Choice::FALSE).to_bool());
731 assert!(Choice::from_u16_eq(1, 1).eq(Choice::TRUE).to_bool());
732 }
733
734 #[test]
735 fn from_u16_le() {
736 assert!(Choice::from_u16_le(0, 0).eq(Choice::TRUE).to_bool());
737 assert!(Choice::from_u16_le(1, 0).eq(Choice::FALSE).to_bool());
738 assert!(Choice::from_u16_le(1, 1).eq(Choice::TRUE).to_bool());
739 assert!(Choice::from_u16_le(1, 2).eq(Choice::TRUE).to_bool());
740 }
741
742 #[test]
743 fn from_u16_lsb() {
744 assert!(Choice::from_u16_lsb(0).eq(Choice::FALSE).to_bool());
745 assert!(Choice::from_u16_lsb(1).eq(Choice::TRUE).to_bool());
746 assert!(Choice::from_u16_lsb(2).eq(Choice::FALSE).to_bool());
747 assert!(Choice::from_u16_lsb(3).eq(Choice::TRUE).to_bool());
748 }
749
750 #[test]
751 fn from_u16_lt() {
752 assert!(Choice::from_u16_lt(0, 0).eq(Choice::FALSE).to_bool());
753 assert!(Choice::from_u16_lt(1, 0).eq(Choice::FALSE).to_bool());
754 assert!(Choice::from_u16_lt(1, 1).eq(Choice::FALSE).to_bool());
755 assert!(Choice::from_u16_lt(1, 2).eq(Choice::TRUE).to_bool());
756 }
757
758 #[test]
759 fn from_u16_nz() {
760 assert!(Choice::from_u16_nz(0).eq(Choice::FALSE).to_bool());
761 assert!(Choice::from_u16_nz(1).eq(Choice::TRUE).to_bool());
762 assert!(Choice::from_u16_nz(2).eq(Choice::TRUE).to_bool());
763 }
764
765 #[test]
766 fn from_u32_eq() {
767 assert!(Choice::from_u32_eq(0, 1).eq(Choice::FALSE).to_bool());
768 assert!(Choice::from_u32_eq(1, 1).eq(Choice::TRUE).to_bool());
769 }
770
771 #[test]
772 fn from_u32_le() {
773 assert!(Choice::from_u32_le(0, 0).eq(Choice::TRUE).to_bool());
774 assert!(Choice::from_u32_le(1, 0).eq(Choice::FALSE).to_bool());
775 assert!(Choice::from_u32_le(1, 1).eq(Choice::TRUE).to_bool());
776 assert!(Choice::from_u32_le(1, 2).eq(Choice::TRUE).to_bool());
777 }
778
779 #[test]
780 fn from_u32_lsb() {
781 assert!(Choice::from_u32_lsb(0).eq(Choice::FALSE).to_bool());
782 assert!(Choice::from_u32_lsb(1).eq(Choice::TRUE).to_bool());
783 assert!(Choice::from_u32_lsb(2).eq(Choice::FALSE).to_bool());
784 assert!(Choice::from_u32_lsb(3).eq(Choice::TRUE).to_bool());
785 }
786
787 #[test]
788 fn from_u32_lt() {
789 assert!(Choice::from_u32_lt(0, 0).eq(Choice::FALSE).to_bool());
790 assert!(Choice::from_u32_lt(1, 0).eq(Choice::FALSE).to_bool());
791 assert!(Choice::from_u32_lt(1, 1).eq(Choice::FALSE).to_bool());
792 assert!(Choice::from_u32_lt(1, 2).eq(Choice::TRUE).to_bool());
793 }
794
795 #[test]
796 fn from_u32_nz() {
797 assert!(Choice::from_u32_nz(0).eq(Choice::FALSE).to_bool());
798 assert!(Choice::from_u32_nz(1).eq(Choice::TRUE).to_bool());
799 assert!(Choice::from_u32_nz(2).eq(Choice::TRUE).to_bool());
800 }
801
802 #[test]
803 fn from_u64_eq() {
804 assert!(Choice::from_u64_eq(0, 1).eq(Choice::FALSE).to_bool());
805 assert!(Choice::from_u64_eq(1, 1).eq(Choice::TRUE).to_bool());
806 }
807
808 #[test]
809 fn from_u64_le() {
810 assert!(Choice::from_u64_le(0, 0).eq(Choice::TRUE).to_bool());
811 assert!(Choice::from_u64_le(1, 0).eq(Choice::FALSE).to_bool());
812 assert!(Choice::from_u64_le(1, 1).eq(Choice::TRUE).to_bool());
813 assert!(Choice::from_u64_le(1, 2).eq(Choice::TRUE).to_bool());
814 }
815
816 #[test]
817 fn from_u64_lsb() {
818 assert!(Choice::from_u64_lsb(0).eq(Choice::FALSE).to_bool());
819 assert!(Choice::from_u64_lsb(1).eq(Choice::TRUE).to_bool());
820 }
821
822 #[test]
823 fn from_u64_lt() {
824 assert!(Choice::from_u64_lt(0, 0).eq(Choice::FALSE).to_bool());
825 assert!(Choice::from_u64_lt(1, 0).eq(Choice::FALSE).to_bool());
826 assert!(Choice::from_u64_lt(1, 1).eq(Choice::FALSE).to_bool());
827 assert!(Choice::from_u64_lt(1, 2).eq(Choice::TRUE).to_bool());
828 }
829
830 #[test]
831 fn from_u64_nz() {
832 assert!(Choice::from_u64_nz(0).eq(Choice::FALSE).to_bool());
833 assert!(Choice::from_u64_nz(1).eq(Choice::TRUE).to_bool());
834 assert!(Choice::from_u64_nz(2).eq(Choice::TRUE).to_bool());
835 }
836
837 #[test]
838 fn from_u128_eq() {
839 assert!(Choice::from_u128_eq(0, 1).eq(Choice::FALSE).to_bool());
840 assert!(Choice::from_u128_eq(1, 1).eq(Choice::TRUE).to_bool());
841 }
842
843 #[test]
844 fn from_u128_le() {
845 assert!(Choice::from_u128_le(0, 0).eq(Choice::TRUE).to_bool());
846 assert!(Choice::from_u128_le(1, 0).eq(Choice::FALSE).to_bool());
847 assert!(Choice::from_u128_le(1, 1).eq(Choice::TRUE).to_bool());
848 assert!(Choice::from_u128_le(1, 2).eq(Choice::TRUE).to_bool());
849 }
850
851 #[test]
852 fn from_u128_lsb() {
853 assert!(Choice::from_u128_lsb(0).eq(Choice::FALSE).to_bool());
854 assert!(Choice::from_u128_lsb(1).eq(Choice::TRUE).to_bool());
855 }
856
857 #[test]
858 fn from_u128_lt() {
859 assert!(Choice::from_u128_lt(0, 0).eq(Choice::FALSE).to_bool());
860 assert!(Choice::from_u128_lt(1, 0).eq(Choice::FALSE).to_bool());
861 assert!(Choice::from_u128_lt(1, 1).eq(Choice::FALSE).to_bool());
862 assert!(Choice::from_u128_lt(1, 2).eq(Choice::TRUE).to_bool());
863 }
864
865 #[test]
866 fn from_u128_nz() {
867 assert!(Choice::from_u128_nz(0).eq(Choice::FALSE).to_bool());
868 assert!(Choice::from_u128_nz(1).eq(Choice::TRUE).to_bool());
869 assert!(Choice::from_u128_nz(2).eq(Choice::TRUE).to_bool());
870 }
871
872 #[test]
873 fn select_i64() {
874 let a: i64 = 1;
875 let b: i64 = 2;
876 assert_eq!(Choice::TRUE.select_i64(a, b), b);
877 assert_eq!(Choice::FALSE.select_i64(a, b), a);
878 }
879
880 #[test]
881 fn select_u8() {
882 let a: u8 = 1;
883 let b: u8 = 2;
884 assert_eq!(Choice::TRUE.select_u8(a, b), b);
885 assert_eq!(Choice::FALSE.select_u8(a, b), a);
886 }
887
888 #[test]
889 fn select_u16() {
890 let a: u16 = 1;
891 let b: u16 = 2;
892 assert_eq!(Choice::TRUE.select_u16(a, b), b);
893 assert_eq!(Choice::FALSE.select_u16(a, b), a);
894 }
895
896 #[test]
897 fn select_u32() {
898 let a: u32 = 1;
899 let b: u32 = 2;
900 assert_eq!(Choice::TRUE.select_u32(a, b), b);
901 assert_eq!(Choice::FALSE.select_u32(a, b), a);
902 }
903
904 #[test]
905 fn select_u64() {
906 let a: u64 = 1;
907 let b: u64 = 2;
908 assert_eq!(Choice::TRUE.select_u64(a, b), b);
909 assert_eq!(Choice::FALSE.select_u64(a, b), a);
910 }
911
912 #[test]
913 fn select_u128() {
914 let a: u128 = 1;
915 let b: u128 = 2;
916 assert_eq!(Choice::TRUE.select_u128(a, b), b);
917 assert_eq!(Choice::FALSE.select_u128(a, b), a);
918 }
919
920 #[test]
921 fn to_bool() {
922 assert!(!Choice::FALSE.to_bool());
923 assert!(Choice::TRUE.to_bool());
924 }
925
926 #[test]
927 fn to_u8() {
928 assert_eq!(Choice::FALSE.to_u8(), 0);
929 assert_eq!(Choice::TRUE.to_u8(), 1);
930 }
931
932 #[test]
933 fn to_u8_mask() {
934 assert_eq!(Choice::FALSE.to_u8_mask(), 0);
935 assert_eq!(Choice::TRUE.to_u8_mask(), u8::MAX);
936 }
937
938 #[test]
939 fn to_u16_mask() {
940 assert_eq!(Choice::FALSE.to_u16_mask(), 0);
941 assert_eq!(Choice::TRUE.to_u16_mask(), u16::MAX);
942 }
943
944 #[test]
945 fn to_u32_mask() {
946 assert_eq!(Choice::FALSE.to_u32_mask(), 0);
947 assert_eq!(Choice::TRUE.to_u32_mask(), u32::MAX);
948 }
949
950 #[test]
951 fn to_u64_mask() {
952 assert_eq!(Choice::FALSE.to_u64_mask(), 0);
953 assert_eq!(Choice::TRUE.to_u64_mask(), u64::MAX);
954 }
955
956 #[test]
957 fn to_u128_mask() {
958 assert_eq!(Choice::FALSE.to_u128_mask(), 0);
959 assert_eq!(Choice::TRUE.to_u128_mask(), u128::MAX);
960 }
961}