competitive/tools/
char_convert.rs1pub trait CharConvertTryInto<T>: Sized {
2 fn into_number(self) -> Option<T>;
4
5 fn into_alphabetic_number(self) -> Option<T>;
7
8 fn into_lower_alphabetic_number(self) -> Option<T>;
10
11 fn into_upper_alphabetic_number(self) -> Option<T>;
13}
14
15pub trait CharConvertTryFrom<T>: Sized {
16 fn from_number(num: T) -> Option<Self>;
18
19 fn from_alphabetic_number(num: T) -> Option<Self>;
21
22 fn from_lower_alphabetic_number(num: T) -> Option<Self>;
24
25 fn from_upper_alphabetic_number(num: T) -> Option<Self>;
27}
28
29macro_rules! impl_char_convert_unsigned {
30 ($($ty:ident)*) => {$(
31 impl CharConvertTryInto<$ty> for char {
32 fn into_number(self) -> Option<$ty> {
33 let num = (self as u8).wrapping_sub(b'0');
34 if num < 10 {
35 Some(num as $ty)
36 } else {
37 None
38 }
39 }
40
41 fn into_alphabetic_number(self) -> Option<$ty> {
42 match self {
43 'A'..='Z' => Some((self as u8 - b'A') as $ty),
44 'a'..='z' => Some((self as u8 - b'a') as $ty),
45 _ => None,
46 }
47 }
48
49 fn into_lower_alphabetic_number(self) -> Option<$ty> {
50 if self.is_ascii_lowercase() {
51 Some((self as u8 - b'a') as $ty)
52 } else {
53 None
54 }
55 }
56
57 fn into_upper_alphabetic_number(self) -> Option<$ty> {
58 if self.is_ascii_uppercase() {
59 Some((self as u8 - b'A') as $ty)
60 } else {
61 None
62 }
63 }
64 }
65
66 impl CharConvertTryFrom<$ty> for char {
67 fn from_number(num: $ty) -> Option<Self> {
68 if num < 10 {
69 Some((b'0' + num as u8) as char)
70 } else {
71 None
72 }
73 }
74
75 fn from_alphabetic_number(num: $ty) -> Option<Self> {
76 if num < 26 {
77 Some((b'A' + num as u8) as char)
78 } else {
79 None
80 }
81 }
82
83 fn from_lower_alphabetic_number(num: $ty) -> Option<Self> {
84 if num < 26 {
85 Some((b'a' + num as u8) as char)
86 } else {
87 None
88 }
89 }
90
91 fn from_upper_alphabetic_number(num: $ty) -> Option<Self> {
92 if num < 26 {
93 Some((b'A' + num as u8) as char)
94 } else {
95 None
96 }
97 }
98 }
99
100 impl CharConvertTryInto<$ty> for u8 {
101 fn into_number(self) -> Option<$ty> {
102 let num = self.wrapping_sub(b'0');
103 if num < 10 {
104 Some(num as $ty)
105 } else {
106 None
107 }
108 }
109
110 fn into_alphabetic_number(self) -> Option<$ty> {
111 match self {
112 b'A'..=b'Z' => Some((self - b'A') as $ty),
113 b'a'..=b'z' => Some((self - b'a') as $ty),
114 _ => None,
115 }
116 }
117
118 fn into_lower_alphabetic_number(self) -> Option<$ty> {
119 if self.is_ascii_lowercase() {
120 Some((self - b'a') as $ty)
121 } else {
122 None
123 }
124 }
125
126 fn into_upper_alphabetic_number(self) -> Option<$ty> {
127 if self.is_ascii_uppercase() {
128 Some((self - b'A') as $ty)
129 } else {
130 None
131 }
132 }
133 }
134
135 impl CharConvertTryFrom<$ty> for u8 {
136 fn from_number(num: $ty) -> Option<Self> {
137 if num < 10 {
138 Some(b'0' + num as u8)
139 } else {
140 None
141 }
142 }
143
144 fn from_alphabetic_number(num: $ty) -> Option<Self> {
145 if num < 26 {
146 Some(b'A' + num as u8)
147 } else {
148 None
149 }
150 }
151
152 fn from_lower_alphabetic_number(num: $ty) -> Option<Self> {
153 if num < 26 {
154 Some(b'a' + num as u8)
155 } else {
156 None
157 }
158 }
159
160 fn from_upper_alphabetic_number(num: $ty) -> Option<Self> {
161 if num < 26 {
162 Some(b'A' + num as u8)
163 } else {
164 None
165 }
166 }
167 }
168 )*};
169}
170impl_char_convert_unsigned!(u8 u16 u32 u64 u128 usize);