digit_sequence/integers/
to_ints.rs1use crate::{CrateError, CrateResult, DigitSequence};
2
3macro_rules! impl_try_to_unsigned {
4 ($type: ty) => {
5 impl TryFrom<DigitSequence> for $type {
11 type Error = CrateError;
12
13 fn try_from(sequence: DigitSequence) -> CrateResult<Self> {
14 (&sequence).try_into()
15 }
16 }
17
18 impl TryFrom<&DigitSequence> for $type {
24 type Error = CrateError;
25
26 fn try_from(sequence: &DigitSequence) -> CrateResult<Self> {
27 let mut result = 0 as Self;
28
29 let enumerated_increasing_digits = sequence.iter().rev().enumerate();
30
31 for (index, &digit) in enumerated_increasing_digits {
32 let power_of_ten: u32 = index.try_into().or(Err(CrateError::Overflow))?;
33
34 let magnitude = (10 as Self)
35 .checked_pow(power_of_ten)
36 .ok_or(CrateError::Overflow)?;
37
38 let addition_term = (digit as Self)
39 .checked_mul(magnitude)
40 .ok_or(CrateError::Overflow)?;
41
42 result = result
43 .checked_add(addition_term)
44 .ok_or(CrateError::Overflow)?;
45 }
46
47 Ok(result)
48 }
49 }
50 };
51}
52
53impl_try_to_unsigned!(u128);
54impl_try_to_unsigned!(u64);
55impl_try_to_unsigned!(u32);
56impl_try_to_unsigned!(u16);
57impl_try_to_unsigned!(u8);
58impl_try_to_unsigned!(usize);
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use crate::test_utils::*;
64 use pretty_assertions::assert_eq;
65
66 #[test]
67 fn roundtrip_convert_0() {
68 expect_try_roundtrip_conversion(0u8);
69 }
70
71 #[test]
72 fn roundtrip_convert_u8() {
73 expect_try_roundtrip_conversion(90u8);
74 }
75
76 #[test]
77 fn roundtrip_convert_u16() {
78 expect_try_roundtrip_conversion(90u16);
79 }
80
81 #[test]
82 fn roundtrip_convert_u32() {
83 expect_try_roundtrip_conversion(90u32);
84 }
85
86 #[test]
87 fn roundtrip_convert_u64() {
88 expect_try_roundtrip_conversion(90u64);
89 }
90
91 #[test]
92 fn roundtrip_convert_u128() {
93 expect_try_roundtrip_conversion(90u128);
94 }
95
96 #[test]
97 fn roundtrip_convert_usize() {
98 expect_try_roundtrip_conversion(90usize);
99 }
100
101 #[test]
102 fn convert_u128_max() {
103 expect_try_roundtrip_conversion(u128::MAX);
104 }
105
106 fn expect_unsigned_overflow(source: &str) {
107 let sequence: DigitSequence = source.parse().unwrap();
108 let conversion_result: CrateResult<u128> = sequence.try_into();
109
110 assert_eq!(conversion_result, Err(CrateError::Overflow));
111 }
112
113 #[test]
114 fn convert_u128_max_plus_one_to_u128() {
115 expect_unsigned_overflow("340282366920938463463374607431768211456");
116 }
117
118 #[test]
119 fn convert_huge_sequence_of_1s_to_u128() {
120 expect_unsigned_overflow("1".repeat(100).as_str());
121 }
122
123 #[test]
124 fn convert_a_1_of_huge_magnitude_to_u128() {
125 expect_unsigned_overflow(&format!("1{}", "0".repeat(100)));
126 }
127
128 #[test]
129 fn roundtrip_convert_0_via_ref() {
130 expect_try_roundtrip_conversion_via_ref(0u8);
131 }
132
133 #[test]
134 fn roundtrip_convert_u8_via_ref() {
135 expect_try_roundtrip_conversion_via_ref(90u8);
136 }
137
138 #[test]
139 fn roundtrip_convert_u16_via_ref() {
140 expect_try_roundtrip_conversion_via_ref(90u16);
141 }
142
143 #[test]
144 fn roundtrip_convert_u32_via_ref() {
145 expect_try_roundtrip_conversion_via_ref(90u32);
146 }
147
148 #[test]
149 fn roundtrip_convert_u64_via_ref() {
150 expect_try_roundtrip_conversion_via_ref(90u64);
151 }
152
153 #[test]
154 fn roundtrip_convert_u128_via_ref() {
155 expect_try_roundtrip_conversion_via_ref(90u128);
156 }
157
158 #[test]
159 fn roundtrip_convert_usize_via_ref() {
160 expect_try_roundtrip_conversion_via_ref(90usize);
161 }
162
163 #[test]
164 fn convert_u128_max_via_ref() {
165 expect_try_roundtrip_conversion_via_ref(u128::MAX);
166 }
167
168 fn expect_unsigned_overflow_via_ref(source: &str) {
169 let sequence: DigitSequence = source.parse().unwrap();
170 let reference = &sequence;
171 let conversion_result: CrateResult<u128> = reference.try_into();
172
173 assert_eq!(conversion_result, Err(CrateError::Overflow));
174 }
175
176 #[test]
177 fn convert_u128_max_plus_one_to_u128_via_ref() {
178 expect_unsigned_overflow_via_ref("340282366920938463463374607431768211456");
179 }
180
181 #[test]
182 fn convert_huge_sequence_of_1s_to_u128_via_ref() {
183 expect_unsigned_overflow_via_ref(&"1".repeat(100));
184 }
185
186 #[test]
187 fn convert_a_1_of_huge_magnitude_to_u128_via_ref() {
188 expect_unsigned_overflow_via_ref(&format!("1{}", "0".repeat(100)));
189 }
190}