rustpython_ruff_python_ast/
int.rs1use std::fmt::Debug;
2use std::str::FromStr;
3
4#[derive(Clone, PartialEq, Eq, Hash)]
6#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
7pub struct Int(Number);
8
9impl FromStr for Int {
10 type Err = std::num::ParseIntError;
11
12 fn from_str(s: &str) -> Result<Self, Self::Err> {
14 match s.parse::<u64>() {
15 Ok(value) => Ok(Int::small(value)),
16 Err(err) => {
17 if matches!(
18 err.kind(),
19 std::num::IntErrorKind::PosOverflow | std::num::IntErrorKind::NegOverflow
20 ) {
21 Ok(Int::big(s))
22 } else {
23 Err(err)
24 }
25 }
26 }
27 }
28}
29
30impl Int {
31 pub const ZERO: Int = Int(Number::Small(0));
32 pub const ONE: Int = Int(Number::Small(1));
33
34 fn small(value: u64) -> Self {
36 Self(Number::Small(value))
37 }
38
39 fn big(value: impl Into<Box<str>>) -> Self {
41 Self(Number::Big(value.into()))
42 }
43
44 pub fn from_str_radix(
49 number: &str,
50 radix: u32,
51 token: &str,
52 ) -> Result<Self, std::num::ParseIntError> {
53 match u64::from_str_radix(number, radix) {
54 Ok(value) => Ok(Int::small(value)),
55 Err(err) => {
56 if matches!(
57 err.kind(),
58 std::num::IntErrorKind::PosOverflow | std::num::IntErrorKind::NegOverflow
59 ) {
60 Ok(Int::big(token))
61 } else {
62 Err(err)
63 }
64 }
65 }
66 }
67
68 pub fn as_u8(&self) -> Option<u8> {
70 match &self.0 {
71 Number::Small(small) => u8::try_from(*small).ok(),
72 Number::Big(_) => None,
73 }
74 }
75
76 pub fn as_u16(&self) -> Option<u16> {
78 match &self.0 {
79 Number::Small(small) => u16::try_from(*small).ok(),
80 Number::Big(_) => None,
81 }
82 }
83
84 pub fn as_u32(&self) -> Option<u32> {
86 match &self.0 {
87 Number::Small(small) => u32::try_from(*small).ok(),
88 Number::Big(_) => None,
89 }
90 }
91
92 pub const fn as_u64(&self) -> Option<u64> {
94 match &self.0 {
95 Number::Small(small) => Some(*small),
96 Number::Big(_) => None,
97 }
98 }
99
100 pub fn as_usize(&self) -> Option<usize> {
102 match &self.0 {
103 Number::Small(small) => usize::try_from(*small).ok(),
104 Number::Big(_) => None,
105 }
106 }
107
108 pub fn as_i8(&self) -> Option<i8> {
110 match &self.0 {
111 Number::Small(small) => i8::try_from(*small).ok(),
112 Number::Big(_) => None,
113 }
114 }
115
116 pub fn as_i16(&self) -> Option<i16> {
118 match &self.0 {
119 Number::Small(small) => i16::try_from(*small).ok(),
120 Number::Big(_) => None,
121 }
122 }
123
124 pub fn as_i32(&self) -> Option<i32> {
126 match &self.0 {
127 Number::Small(small) => i32::try_from(*small).ok(),
128 Number::Big(_) => None,
129 }
130 }
131
132 pub fn as_i64(&self) -> Option<i64> {
134 match &self.0 {
135 Number::Small(small) => i64::try_from(*small).ok(),
136 Number::Big(_) => None,
137 }
138 }
139}
140
141impl std::fmt::Display for Int {
142 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 write!(f, "{}", self.0)
144 }
145}
146
147impl Debug for Int {
148 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149 std::fmt::Display::fmt(self, f)
150 }
151}
152
153impl PartialEq<u8> for Int {
154 fn eq(&self, other: &u8) -> bool {
155 self.as_u8() == Some(*other)
156 }
157}
158
159impl PartialEq<u16> for Int {
160 fn eq(&self, other: &u16) -> bool {
161 self.as_u16() == Some(*other)
162 }
163}
164
165impl PartialEq<u32> for Int {
166 fn eq(&self, other: &u32) -> bool {
167 self.as_u32() == Some(*other)
168 }
169}
170
171impl PartialEq<i8> for Int {
172 fn eq(&self, other: &i8) -> bool {
173 self.as_i8() == Some(*other)
174 }
175}
176
177impl PartialEq<i16> for Int {
178 fn eq(&self, other: &i16) -> bool {
179 self.as_i16() == Some(*other)
180 }
181}
182
183impl PartialEq<i32> for Int {
184 fn eq(&self, other: &i32) -> bool {
185 self.as_i32() == Some(*other)
186 }
187}
188
189impl PartialEq<i64> for Int {
190 fn eq(&self, other: &i64) -> bool {
191 self.as_i64() == Some(*other)
192 }
193}
194
195impl From<u8> for Int {
196 fn from(value: u8) -> Self {
197 Self::small(u64::from(value))
198 }
199}
200
201impl From<u16> for Int {
202 fn from(value: u16) -> Self {
203 Self::small(u64::from(value))
204 }
205}
206
207impl From<u32> for Int {
208 fn from(value: u32) -> Self {
209 Self::small(u64::from(value))
210 }
211}
212
213impl From<u64> for Int {
214 fn from(value: u64) -> Self {
215 Self::small(value)
216 }
217}
218
219#[derive(Debug, Clone, PartialEq, Eq, Hash)]
220#[cfg_attr(feature = "get-size", derive(get_size2::GetSize))]
221enum Number {
222 Small(u64),
224 Big(Box<str>),
226}
227
228impl std::fmt::Display for Number {
229 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
230 match self {
231 Number::Small(value) => write!(f, "{value}"),
232 Number::Big(value) => write!(f, "{value}"),
233 }
234 }
235}