fixed_bigint/fixeduint/
num_traits_casts.rs1use super::{FixedUInt, MachineWord};
2use crate::personality::Personality;
3use num_traits::{Bounded, FromPrimitive, ToPrimitive};
4
5impl<T: MachineWord, const N: usize, P: Personality> num_traits::NumCast for FixedUInt<T, N, P> {
6 fn from<X>(arg: X) -> Option<Self>
7 where
8 X: ToPrimitive,
9 {
10 Self::from_u64(arg.to_u64()?)
11 }
12}
13
14impl<T: MachineWord, const N: usize, P: Personality> num_traits::ToPrimitive
15 for FixedUInt<T, N, P>
16{
17 fn to_i64(&self) -> Option<i64> {
18 None
19 }
20 fn to_u64(&self) -> Option<u64> {
21 let mut ret: u64 = 0;
22 let iter_limit = core::cmp::min(8 / Self::WORD_SIZE, N);
25
26 for i in iter_limit..N {
28 if self.array[i] != T::zero() {
29 return None;
30 }
31 }
32
33 for (i, word) in self.array.iter().take(iter_limit).enumerate() {
34 let bytes = word.to_le_bytes();
36
37 for (j, &byte) in bytes.as_ref().iter().enumerate() {
39 let bit_shift = (i * Self::WORD_SIZE + j) * 8;
41
42 if bit_shift < 64 {
44 ret |= (byte as u64) << bit_shift;
45 }
46 }
47 }
48
49 Some(ret)
50 }
51}
52
53impl<T: MachineWord, const N: usize, P: Personality> num_traits::FromPrimitive
54 for FixedUInt<T, N, P>
55{
56 fn from_i64(_: i64) -> Option<Self> {
57 None
58 }
59 fn from_u64(input: u64) -> Option<Self> {
60 if let Some(max) = Self::max_value().to_u64() {
64 if input > max {
65 return None;
66 }
67 }
68 Some(Self::from_le_bytes(&input.to_le_bytes()))
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 fn cast<T: num_traits::NumCast + PartialEq>(a: u32, b: u8) -> bool {
77 let my_a = T::from(a).unwrap();
78 let my_b = T::from(b).unwrap();
79 my_a == my_b
80 }
81
82 type Fixed = FixedUInt<u8, 1>;
83 #[test]
85 fn test_numcast() {
86 assert!(cast::<Fixed>(123, 123));
87 assert!(cast::<Fixed>(225, 225));
88 }
89}