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 pub const fn from_i64_eq(x: i64, y: i64) -> Self {
112 Self::from_u64_nz(x as u64 ^ y as u64).not()
113 }
114
115 #[inline]
119 #[must_use]
120 pub const fn from_u8_eq(x: u8, y: u8) -> Self {
121 Self::from_u8_nz(x ^ y).not()
122 }
123
124 #[inline]
126 #[must_use]
127 pub const fn from_u8_le(x: u8, y: u8) -> Self {
128 Self::from_u8_lsb(bitle!(x, y, u8::BITS))
129 }
130
131 #[inline]
133 #[must_use]
134 pub const fn from_u8_lsb(value: u8) -> Self {
135 Self(value & 0x1)
136 }
137
138 #[inline]
140 #[must_use]
141 pub const fn from_u8_lt(x: u8, y: u8) -> Self {
142 Self::from_u8_lsb(bitlt!(x, y, u8::BITS))
143 }
144
145 #[inline]
147 #[must_use]
148 pub const fn from_u8_nz(value: u8) -> Self {
149 Self::from_u8_lsb(bitnz!(value, u8::BITS))
150 }
151
152 #[inline]
156 #[must_use]
157 pub const fn from_u16_eq(x: u16, y: u16) -> Self {
158 Self::from_u16_nz(x ^ y).not()
159 }
160
161 #[inline]
163 #[must_use]
164 pub const fn from_u16_le(x: u16, y: u16) -> Self {
165 Self::from_u16_lsb(bitle!(x, y, u16::BITS))
166 }
167
168 #[inline]
170 #[must_use]
171 pub const fn from_u16_lsb(value: u16) -> Self {
172 Self((value & 0x1) as u8)
173 }
174
175 #[inline]
177 #[must_use]
178 pub const fn from_u16_lt(x: u16, y: u16) -> Self {
179 Self::from_u16_lsb(bitlt!(x, y, u16::BITS))
180 }
181
182 #[inline]
184 #[must_use]
185 pub const fn from_u16_nz(value: u16) -> Self {
186 Self::from_u16_lsb(bitnz!(value, u16::BITS))
187 }
188
189 #[inline]
193 #[must_use]
194 pub const fn from_u32_eq(x: u32, y: u32) -> Self {
195 Self::from_u32_nz(x ^ y).not()
196 }
197
198 #[inline]
200 #[must_use]
201 pub const fn from_u32_le(x: u32, y: u32) -> Self {
202 Self::from_u32_lsb(bitle!(x, y, u32::BITS))
203 }
204
205 #[inline]
207 #[must_use]
208 pub const fn from_u32_lsb(value: u32) -> Self {
209 Self((value & 0x1) as u8)
210 }
211
212 #[inline]
214 #[must_use]
215 pub const fn from_u32_lt(x: u32, y: u32) -> Self {
216 Self::from_u32_lsb(bitlt!(x, y, u32::BITS))
217 }
218
219 #[inline]
221 #[must_use]
222 pub const fn from_u32_nz(value: u32) -> Self {
223 Self::from_u32_lsb(bitnz!(value, u32::BITS))
224 }
225
226 #[inline]
230 #[must_use]
231 pub const fn from_u64_eq(x: u64, y: u64) -> Self {
232 Self::from_u64_nz(x ^ y).not()
233 }
234
235 #[inline]
237 #[must_use]
238 pub const fn from_u64_le(x: u64, y: u64) -> Self {
239 Self::from_u64_lsb(bitle!(x, y, u64::BITS))
240 }
241
242 #[inline]
244 #[must_use]
245 pub const fn from_u64_lsb(value: u64) -> Self {
246 Self((value & 0x1) as u8)
247 }
248
249 #[inline]
251 #[must_use]
252 pub const fn from_u64_lt(x: u64, y: u64) -> Self {
253 Self::from_u64_lsb(bitlt!(x, y, u64::BITS))
254 }
255
256 #[inline]
258 #[must_use]
259 pub const fn from_u64_nz(value: u64) -> Self {
260 Self::from_u64_lsb(bitnz!(value, u64::BITS))
261 }
262
263 #[inline]
267 #[must_use]
268 pub const fn from_u128_eq(x: u128, y: u128) -> Self {
269 Self::from_u128_nz(x ^ y).not()
270 }
271
272 #[inline]
274 #[must_use]
275 pub const fn from_u128_le(x: u128, y: u128) -> Self {
276 Self::from_u128_lsb(bitle!(x, y, u128::BITS))
277 }
278
279 #[inline]
281 #[must_use]
282 pub const fn from_u128_lsb(value: u128) -> Self {
283 Self((value & 1) as u8)
284 }
285
286 #[inline]
288 #[must_use]
289 pub const fn from_u128_lt(x: u128, y: u128) -> Self {
290 Self::from_u128_lsb(bitlt!(x, y, u128::BITS))
291 }
292
293 #[inline]
295 #[must_use]
296 pub const fn from_u128_nz(value: u128) -> Self {
297 Self::from_u128_lsb(bitnz!(value, u128::BITS))
298 }
299
300 #[inline]
309 #[must_use]
310 pub const fn select_i64(self, a: i64, b: i64) -> i64 {
311 self.select_u64(a as u64, b as u64) as i64
312 }
313
314 #[inline]
319 #[must_use]
320 pub const fn select_u8(self, a: u8, b: u8) -> u8 {
321 a ^ (self.to_u8_mask() & (a ^ b))
322 }
323
324 #[inline]
329 #[must_use]
330 pub const fn select_u16(self, a: u16, b: u16) -> u16 {
331 a ^ (self.to_u16_mask() & (a ^ b))
332 }
333
334 #[inline]
339 #[must_use]
340 pub const fn select_u32(self, a: u32, b: u32) -> u32 {
341 a ^ (self.to_u32_mask() & (a ^ b))
342 }
343
344 #[inline]
349 #[must_use]
350 pub const fn select_u64(self, a: u64, b: u64) -> u64 {
351 a ^ (self.to_u64_mask() & (a ^ b))
352 }
353
354 #[inline]
359 #[must_use]
360 pub const fn select_u128(self, a: u128, b: u128) -> u128 {
361 a ^ (self.to_u128_mask() & (a ^ b))
362 }
363
364 #[must_use]
387 pub fn to_bool(self) -> bool {
388 self.to_u8() != 0
389 }
390
391 #[must_use]
394 pub fn to_u8(self) -> u8 {
395 core::hint::black_box(self.0)
399 }
400
401 #[must_use]
412 pub const fn to_bool_vartime(self) -> bool {
413 self.0 != 0
414 }
415
416 #[must_use]
421 pub const fn to_u8_vartime(self) -> u8 {
422 self.0
423 }
424
425 #[inline]
431 #[must_use]
432 pub const fn to_u8_mask(self) -> u8 {
433 self.0.wrapping_neg()
434 }
435
436 #[inline]
442 #[must_use]
443 pub const fn to_u16_mask(self) -> u16 {
444 (self.0 as u16).wrapping_neg()
445 }
446
447 #[inline]
453 #[must_use]
454 pub const fn to_u32_mask(self) -> u32 {
455 (self.0 as u32).wrapping_neg()
456 }
457
458 #[inline]
464 #[must_use]
465 pub const fn to_u64_mask(self) -> u64 {
466 (self.0 as u64).wrapping_neg()
467 }
468
469 #[inline]
475 #[must_use]
476 pub const fn to_u128_mask(self) -> u128 {
477 (self.0 as u128).wrapping_neg()
478 }
479}
480
481impl BitAnd for Choice {
482 type Output = Choice;
483
484 #[inline]
485 fn bitand(self, rhs: Choice) -> Choice {
486 self.and(rhs)
487 }
488}
489
490impl BitAndAssign for Choice {
491 #[inline]
492 fn bitand_assign(&mut self, rhs: Choice) {
493 *self = *self & rhs;
494 }
495}
496
497impl BitOr for Choice {
498 type Output = Choice;
499
500 #[inline]
501 fn bitor(self, rhs: Choice) -> Choice {
502 self.or(rhs)
503 }
504}
505
506impl BitOrAssign for Choice {
507 #[inline]
508 fn bitor_assign(&mut self, rhs: Choice) {
509 *self = *self | rhs;
510 }
511}
512
513impl BitXor for Choice {
514 type Output = Choice;
515
516 #[inline]
517 fn bitxor(self, rhs: Choice) -> Choice {
518 Choice(self.0 ^ rhs.0)
519 }
520}
521
522impl BitXorAssign for Choice {
523 #[inline]
524 fn bitxor_assign(&mut self, rhs: Choice) {
525 *self = *self ^ rhs;
526 }
527}
528
529impl CtAssign for Choice {
530 #[inline]
531 fn ct_assign(&mut self, other: &Self, choice: Choice) {
532 self.0.ct_assign(&other.0, choice);
533 }
534}
535impl CtAssignSlice for Choice {}
536impl CtSelectUsingCtAssign for Choice {}
537
538impl CtEq for Choice {
539 #[inline]
540 fn ct_eq(&self, other: &Self) -> Self {
541 self.0.ct_eq(&other.0)
542 }
543}
544impl CtEqSlice for Choice {}
545
546impl From<u8> for Choice {
555 fn from(value: u8) -> Self {
556 Choice::from_u8_lsb(value)
557 }
558}
559
560impl From<Choice> for u8 {
561 fn from(choice: Choice) -> u8 {
562 choice.to_u8()
563 }
564}
565
566impl From<Choice> for bool {
577 fn from(choice: Choice) -> bool {
578 choice.to_bool()
579 }
580}
581
582impl Not for Choice {
583 type Output = Choice;
584
585 #[inline]
586 fn not(self) -> Choice {
587 self.not()
588 }
589}
590
591#[cfg(feature = "subtle")]
592impl From<subtle::Choice> for Choice {
593 #[inline]
594 fn from(choice: subtle::Choice) -> Choice {
595 Choice(choice.unwrap_u8())
596 }
597}
598
599#[cfg(feature = "subtle")]
600impl From<Choice> for subtle::Choice {
601 #[inline]
602 fn from(choice: Choice) -> subtle::Choice {
603 subtle::Choice::from(choice.0)
604 }
605}
606
607#[cfg(feature = "subtle")]
608impl subtle::ConditionallySelectable for Choice {
609 #[inline]
610 fn conditional_select(a: &Self, b: &Self, choice: subtle::Choice) -> Self {
611 CtSelect::ct_select(a, b, choice.into())
612 }
613}
614
615#[cfg(feature = "subtle")]
616impl subtle::ConstantTimeEq for Choice {
617 #[inline]
618 fn ct_eq(&self, other: &Self) -> subtle::Choice {
619 CtEq::ct_eq(self, other).into()
620 }
621}
622
623#[cfg(test)]
624mod tests {
625 use super::Choice;
626 use crate::{CtEq, CtSelect};
627
628 #[test]
629 fn ct_eq() {
630 let a = Choice::TRUE;
631 let b = Choice::TRUE;
632 let c = Choice::FALSE;
633
634 assert!(a.ct_eq(&b).to_bool());
635 assert!(!a.ct_eq(&c).to_bool());
636 assert!(!b.ct_eq(&c).to_bool());
637
638 assert!(!a.ct_ne(&b).to_bool());
639 assert!(a.ct_ne(&c).to_bool());
640 assert!(b.ct_ne(&c).to_bool());
641 }
642
643 #[test]
644 fn ct_select() {
645 let a = Choice::FALSE;
646 let b = Choice::TRUE;
647 assert_eq!(a.ct_select(&b, Choice::FALSE).to_bool(), a.to_bool());
648 assert_eq!(a.ct_select(&b, Choice::TRUE).to_bool(), b.to_bool());
649 }
650
651 #[test]
652 fn and() {
653 assert_eq!((Choice::FALSE & Choice::FALSE).to_u8(), 0);
654 assert_eq!((Choice::TRUE & Choice::FALSE).to_u8(), 0);
655 assert_eq!((Choice::FALSE & Choice::TRUE).to_u8(), 0);
656 assert_eq!((Choice::TRUE & Choice::TRUE).to_u8(), 1);
657 }
658
659 #[test]
660 fn or() {
661 assert_eq!((Choice::FALSE | Choice::FALSE).to_u8(), 0);
662 assert_eq!((Choice::TRUE | Choice::FALSE).to_u8(), 1);
663 assert_eq!((Choice::FALSE | Choice::TRUE).to_u8(), 1);
664 assert_eq!((Choice::TRUE | Choice::TRUE).to_u8(), 1);
665 }
666
667 #[test]
668 fn xor() {
669 assert_eq!((Choice::FALSE ^ Choice::FALSE).to_u8(), 0);
670 assert_eq!((Choice::TRUE ^ Choice::FALSE).to_u8(), 1);
671 assert_eq!((Choice::FALSE ^ Choice::TRUE).to_u8(), 1);
672 assert_eq!((Choice::TRUE ^ Choice::TRUE).to_u8(), 0);
673 }
674
675 #[test]
676 fn not() {
677 assert_eq!(Choice::FALSE.not().to_u8(), 1);
678 assert_eq!(Choice::TRUE.not().to_u8(), 0);
679 }
680
681 #[test]
682 fn from_i64_eq() {
683 assert!(Choice::from_i64_eq(0, 1).eq(Choice::FALSE).to_bool());
684 assert!(Choice::from_i64_eq(1, 1).eq(Choice::TRUE).to_bool());
685 }
686
687 #[test]
688 fn from_u8_eq() {
689 assert!(Choice::from_u8_eq(0, 1).eq(Choice::FALSE).to_bool());
690 assert!(Choice::from_u8_eq(1, 1).eq(Choice::TRUE).to_bool());
691 }
692
693 #[test]
694 fn from_u8_le() {
695 assert!(Choice::from_u8_le(0, 0).eq(Choice::TRUE).to_bool());
696 assert!(Choice::from_u8_le(1, 0).eq(Choice::FALSE).to_bool());
697 assert!(Choice::from_u8_le(1, 1).eq(Choice::TRUE).to_bool());
698 assert!(Choice::from_u8_le(1, 2).eq(Choice::TRUE).to_bool());
699 }
700
701 #[test]
702 fn from_u8_lsb() {
703 assert!(Choice::from_u8_lsb(0).eq(Choice::FALSE).to_bool());
704 assert!(Choice::from_u8_lsb(1).eq(Choice::TRUE).to_bool());
705 assert!(Choice::from_u8_lsb(2).eq(Choice::FALSE).to_bool());
706 assert!(Choice::from_u8_lsb(3).eq(Choice::TRUE).to_bool());
707 }
708
709 #[test]
710 fn from_u8_lt() {
711 assert!(Choice::from_u8_lt(0, 0).eq(Choice::FALSE).to_bool());
712 assert!(Choice::from_u8_lt(1, 0).eq(Choice::FALSE).to_bool());
713 assert!(Choice::from_u8_lt(1, 1).eq(Choice::FALSE).to_bool());
714 assert!(Choice::from_u8_lt(1, 2).eq(Choice::TRUE).to_bool());
715 }
716
717 #[test]
718 fn from_u8_nz() {
719 assert!(Choice::from_u8_nz(0).eq(Choice::FALSE).to_bool());
720 assert!(Choice::from_u8_nz(1).eq(Choice::TRUE).to_bool());
721 assert!(Choice::from_u8_nz(2).eq(Choice::TRUE).to_bool());
722 }
723
724 #[test]
725 fn from_u16_eq() {
726 assert!(Choice::from_u16_eq(0, 1).eq(Choice::FALSE).to_bool());
727 assert!(Choice::from_u16_eq(1, 1).eq(Choice::TRUE).to_bool());
728 }
729
730 #[test]
731 fn from_u16_le() {
732 assert!(Choice::from_u16_le(0, 0).eq(Choice::TRUE).to_bool());
733 assert!(Choice::from_u16_le(1, 0).eq(Choice::FALSE).to_bool());
734 assert!(Choice::from_u16_le(1, 1).eq(Choice::TRUE).to_bool());
735 assert!(Choice::from_u16_le(1, 2).eq(Choice::TRUE).to_bool());
736 }
737
738 #[test]
739 fn from_u16_lsb() {
740 assert!(Choice::from_u16_lsb(0).eq(Choice::FALSE).to_bool());
741 assert!(Choice::from_u16_lsb(1).eq(Choice::TRUE).to_bool());
742 assert!(Choice::from_u16_lsb(2).eq(Choice::FALSE).to_bool());
743 assert!(Choice::from_u16_lsb(3).eq(Choice::TRUE).to_bool());
744 }
745
746 #[test]
747 fn from_u16_lt() {
748 assert!(Choice::from_u16_lt(0, 0).eq(Choice::FALSE).to_bool());
749 assert!(Choice::from_u16_lt(1, 0).eq(Choice::FALSE).to_bool());
750 assert!(Choice::from_u16_lt(1, 1).eq(Choice::FALSE).to_bool());
751 assert!(Choice::from_u16_lt(1, 2).eq(Choice::TRUE).to_bool());
752 }
753
754 #[test]
755 fn from_u16_nz() {
756 assert!(Choice::from_u16_nz(0).eq(Choice::FALSE).to_bool());
757 assert!(Choice::from_u16_nz(1).eq(Choice::TRUE).to_bool());
758 assert!(Choice::from_u16_nz(2).eq(Choice::TRUE).to_bool());
759 }
760
761 #[test]
762 fn from_u32_eq() {
763 assert!(Choice::from_u32_eq(0, 1).eq(Choice::FALSE).to_bool());
764 assert!(Choice::from_u32_eq(1, 1).eq(Choice::TRUE).to_bool());
765 }
766
767 #[test]
768 fn from_u32_le() {
769 assert!(Choice::from_u32_le(0, 0).eq(Choice::TRUE).to_bool());
770 assert!(Choice::from_u32_le(1, 0).eq(Choice::FALSE).to_bool());
771 assert!(Choice::from_u32_le(1, 1).eq(Choice::TRUE).to_bool());
772 assert!(Choice::from_u32_le(1, 2).eq(Choice::TRUE).to_bool());
773 }
774
775 #[test]
776 fn from_u32_lsb() {
777 assert!(Choice::from_u32_lsb(0).eq(Choice::FALSE).to_bool());
778 assert!(Choice::from_u32_lsb(1).eq(Choice::TRUE).to_bool());
779 assert!(Choice::from_u32_lsb(2).eq(Choice::FALSE).to_bool());
780 assert!(Choice::from_u32_lsb(3).eq(Choice::TRUE).to_bool());
781 }
782
783 #[test]
784 fn from_u32_lt() {
785 assert!(Choice::from_u32_lt(0, 0).eq(Choice::FALSE).to_bool());
786 assert!(Choice::from_u32_lt(1, 0).eq(Choice::FALSE).to_bool());
787 assert!(Choice::from_u32_lt(1, 1).eq(Choice::FALSE).to_bool());
788 assert!(Choice::from_u32_lt(1, 2).eq(Choice::TRUE).to_bool());
789 }
790
791 #[test]
792 fn from_u32_nz() {
793 assert!(Choice::from_u32_nz(0).eq(Choice::FALSE).to_bool());
794 assert!(Choice::from_u32_nz(1).eq(Choice::TRUE).to_bool());
795 assert!(Choice::from_u32_nz(2).eq(Choice::TRUE).to_bool());
796 }
797
798 #[test]
799 fn from_u64_eq() {
800 assert!(Choice::from_u64_eq(0, 1).eq(Choice::FALSE).to_bool());
801 assert!(Choice::from_u64_eq(1, 1).eq(Choice::TRUE).to_bool());
802 }
803
804 #[test]
805 fn from_u64_le() {
806 assert!(Choice::from_u64_le(0, 0).eq(Choice::TRUE).to_bool());
807 assert!(Choice::from_u64_le(1, 0).eq(Choice::FALSE).to_bool());
808 assert!(Choice::from_u64_le(1, 1).eq(Choice::TRUE).to_bool());
809 assert!(Choice::from_u64_le(1, 2).eq(Choice::TRUE).to_bool());
810 }
811
812 #[test]
813 fn from_u64_lsb() {
814 assert!(Choice::from_u64_lsb(0).eq(Choice::FALSE).to_bool());
815 assert!(Choice::from_u64_lsb(1).eq(Choice::TRUE).to_bool());
816 }
817
818 #[test]
819 fn from_u64_lt() {
820 assert!(Choice::from_u64_lt(0, 0).eq(Choice::FALSE).to_bool());
821 assert!(Choice::from_u64_lt(1, 0).eq(Choice::FALSE).to_bool());
822 assert!(Choice::from_u64_lt(1, 1).eq(Choice::FALSE).to_bool());
823 assert!(Choice::from_u64_lt(1, 2).eq(Choice::TRUE).to_bool());
824 }
825
826 #[test]
827 fn from_u64_nz() {
828 assert!(Choice::from_u64_nz(0).eq(Choice::FALSE).to_bool());
829 assert!(Choice::from_u64_nz(1).eq(Choice::TRUE).to_bool());
830 assert!(Choice::from_u64_nz(2).eq(Choice::TRUE).to_bool());
831 }
832
833 #[test]
834 fn from_u128_eq() {
835 assert!(Choice::from_u128_eq(0, 1).eq(Choice::FALSE).to_bool());
836 assert!(Choice::from_u128_eq(1, 1).eq(Choice::TRUE).to_bool());
837 }
838
839 #[test]
840 fn from_u128_le() {
841 assert!(Choice::from_u128_le(0, 0).eq(Choice::TRUE).to_bool());
842 assert!(Choice::from_u128_le(1, 0).eq(Choice::FALSE).to_bool());
843 assert!(Choice::from_u128_le(1, 1).eq(Choice::TRUE).to_bool());
844 assert!(Choice::from_u128_le(1, 2).eq(Choice::TRUE).to_bool());
845 }
846
847 #[test]
848 fn from_u128_lsb() {
849 assert!(Choice::from_u128_lsb(0).eq(Choice::FALSE).to_bool());
850 assert!(Choice::from_u128_lsb(1).eq(Choice::TRUE).to_bool());
851 }
852
853 #[test]
854 fn from_u128_lt() {
855 assert!(Choice::from_u128_lt(0, 0).eq(Choice::FALSE).to_bool());
856 assert!(Choice::from_u128_lt(1, 0).eq(Choice::FALSE).to_bool());
857 assert!(Choice::from_u128_lt(1, 1).eq(Choice::FALSE).to_bool());
858 assert!(Choice::from_u128_lt(1, 2).eq(Choice::TRUE).to_bool());
859 }
860
861 #[test]
862 fn from_u128_nz() {
863 assert!(Choice::from_u128_nz(0).eq(Choice::FALSE).to_bool());
864 assert!(Choice::from_u128_nz(1).eq(Choice::TRUE).to_bool());
865 assert!(Choice::from_u128_nz(2).eq(Choice::TRUE).to_bool());
866 }
867
868 #[test]
869 fn select_i64() {
870 let a: i64 = 1;
871 let b: i64 = 2;
872 assert_eq!(Choice::TRUE.select_i64(a, b), b);
873 assert_eq!(Choice::FALSE.select_i64(a, b), a);
874 }
875
876 #[test]
877 fn select_u8() {
878 let a: u8 = 1;
879 let b: u8 = 2;
880 assert_eq!(Choice::TRUE.select_u8(a, b), b);
881 assert_eq!(Choice::FALSE.select_u8(a, b), a);
882 }
883
884 #[test]
885 fn select_u16() {
886 let a: u16 = 1;
887 let b: u16 = 2;
888 assert_eq!(Choice::TRUE.select_u16(a, b), b);
889 assert_eq!(Choice::FALSE.select_u16(a, b), a);
890 }
891
892 #[test]
893 fn select_u32() {
894 let a: u32 = 1;
895 let b: u32 = 2;
896 assert_eq!(Choice::TRUE.select_u32(a, b), b);
897 assert_eq!(Choice::FALSE.select_u32(a, b), a);
898 }
899
900 #[test]
901 fn select_u64() {
902 let a: u64 = 1;
903 let b: u64 = 2;
904 assert_eq!(Choice::TRUE.select_u64(a, b), b);
905 assert_eq!(Choice::FALSE.select_u64(a, b), a);
906 }
907
908 #[test]
909 fn select_u128() {
910 let a: u128 = 1;
911 let b: u128 = 2;
912 assert_eq!(Choice::TRUE.select_u128(a, b), b);
913 assert_eq!(Choice::FALSE.select_u128(a, b), a);
914 }
915
916 #[test]
917 fn to_bool() {
918 assert!(!Choice::FALSE.to_bool());
919 assert!(Choice::TRUE.to_bool());
920 }
921
922 #[test]
923 fn to_u8() {
924 assert_eq!(Choice::FALSE.to_u8(), 0);
925 assert_eq!(Choice::TRUE.to_u8(), 1);
926 }
927
928 #[test]
929 fn to_u8_mask() {
930 assert_eq!(Choice::FALSE.to_u8_mask(), 0);
931 assert_eq!(Choice::TRUE.to_u8_mask(), u8::MAX);
932 }
933
934 #[test]
935 fn to_u16_mask() {
936 assert_eq!(Choice::FALSE.to_u16_mask(), 0);
937 assert_eq!(Choice::TRUE.to_u16_mask(), u16::MAX);
938 }
939
940 #[test]
941 fn to_u32_mask() {
942 assert_eq!(Choice::FALSE.to_u32_mask(), 0);
943 assert_eq!(Choice::TRUE.to_u32_mask(), u32::MAX);
944 }
945
946 #[test]
947 fn to_u64_mask() {
948 assert_eq!(Choice::FALSE.to_u64_mask(), 0);
949 assert_eq!(Choice::TRUE.to_u64_mask(), u64::MAX);
950 }
951
952 #[test]
953 fn to_u128_mask() {
954 assert_eq!(Choice::FALSE.to_u128_mask(), 0);
955 assert_eq!(Choice::TRUE.to_u128_mask(), u128::MAX);
956 }
957}