digit_sequence/integers/
from_ints.rs1use crate::{CrateError, CrateResult, DigitSequence};
2use std::collections::LinkedList;
3
4macro_rules! impl_try_from_signed {
5 ($type: ty) => {
6 impl TryFrom<$type> for DigitSequence {
10 type Error = CrateError;
11
12 fn try_from(value: $type) -> CrateResult<Self> {
13 if value < 0 {
14 return Err(CrateError::NegativeNumber(value as i128));
15 }
16
17 Ok(convert_from_positive!(value))
18 }
19 }
20 };
21}
22
23macro_rules! impl_from_unsigned {
24 ($type: ty) => {
25 impl From<$type> for DigitSequence {
28 fn from(value: $type) -> DigitSequence {
29 convert_from_positive!(value)
30 }
31 }
32 };
33}
34
35macro_rules! convert_from_positive {
36 ($value: ident) => {{
37 let mut result = LinkedList::new();
38 let mut current_value = $value;
39
40 loop {
41 let digit = current_value % 10;
42
43 result.push_front(digit as u8);
44
45 current_value /= 10;
46
47 if current_value == 0 {
48 break;
49 }
50 }
51
52 DigitSequence(result.into_iter().collect())
53 }};
54}
55
56impl_try_from_signed!(i128);
57impl_try_from_signed!(i64);
58impl_try_from_signed!(i32);
59impl_try_from_signed!(i16);
60impl_try_from_signed!(i8);
61impl_try_from_signed!(isize);
62
63impl_from_unsigned!(u128);
64impl_from_unsigned!(u64);
65impl_from_unsigned!(u32);
66impl_from_unsigned!(u16);
67impl_from_unsigned!(u8);
68impl_from_unsigned!(usize);
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use crate::test_utils::{expect_digits_from, expect_try_digits_from};
74 use pretty_assertions::assert_eq;
75
76 #[test]
77 fn convert_0() {
78 let digit_sequence: DigitSequence = 0u8.into();
79
80 assert_eq!(digit_sequence, [0]);
81 }
82
83 #[test]
84 fn convert_negative_number() {
85 let result: CrateResult<DigitSequence> = (-4).try_into();
86
87 assert_eq!(result, Err(CrateError::NegativeNumber(-4)));
88 }
89
90 #[test]
91 fn convert_u8() {
92 expect_digits_from(107u8, &[1, 0, 7])
93 }
94
95 #[test]
96 fn convert_u16() {
97 expect_digits_from(107u16, &[1, 0, 7])
98 }
99
100 #[test]
101 fn convert_u32() {
102 expect_digits_from(107u32, &[1, 0, 7])
103 }
104
105 #[test]
106 fn convert_u64() {
107 expect_digits_from(107u64, &[1, 0, 7])
108 }
109
110 #[test]
111 fn convert_u128() {
112 expect_digits_from(107u128, &[1, 0, 7])
113 }
114
115 #[test]
116 fn convert_usize() {
117 expect_digits_from(107usize, &[1, 0, 7])
118 }
119
120 #[test]
121 fn convert_i8() {
122 expect_try_digits_from(107i8, &[1, 0, 7])
123 }
124
125 #[test]
126 fn convert_i16() {
127 expect_try_digits_from(107i16, &[1, 0, 7])
128 }
129
130 #[test]
131 fn convert_i32() {
132 expect_try_digits_from(107i32, &[1, 0, 7])
133 }
134
135 #[test]
136 fn convert_i64() {
137 expect_try_digits_from(107i64, &[1, 0, 7])
138 }
139
140 #[test]
141 fn convert_i128() {
142 expect_try_digits_from(107i128, &[1, 0, 7])
143 }
144
145 #[test]
146 fn convert_isize() {
147 expect_try_digits_from(107isize, &[1, 0, 7])
148 }
149}