1pub mod prelude;
5
6#[derive(Debug, Clone, PartialEq)]
8pub enum ConversionError {
9 Error(String, String),
10}
11impl ConversionError {
12 pub(crate) fn error<F: Into<String>, M: Into<String>>(from: F, msg: M) -> Self {
13 return Self::Error(from.into(), msg.into());
14 }
15}
16impl std::fmt::Display for ConversionError {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 match self {
19 ConversionError::Error(from, msg) => write!(f, "Error({}, {})", from, msg),
20 }
21 }
22}
23pub trait GoToU8 {fn goto_u8(&self) -> u8;}
27pub trait GoToU16 {fn goto_u16(&self) -> u16;}
28pub trait GoToU32 {fn goto_u32(&self) -> u32;}
29pub trait GoToU64 {fn goto_u64(&self) -> u64;}
30pub trait GoToU128 {fn goto_u128(&self) -> u128;}
31pub trait GoToUsize {fn goto_usize(&self) -> usize;}
32pub trait GoToF32 {fn goto_f32(&self) -> f32;}
33pub trait GoToF64 {fn goto_f64(&self) -> f64;}
34pub trait TryGoToU8 {fn try_goto_u8(&self) -> Result<u8, ConversionError>;}
35pub trait TryGoToU16 {fn try_goto_u16(&self) -> Result<u16, ConversionError>;}
36pub trait TryGoToU32 {fn try_goto_u32(&self) -> Result<u32, ConversionError>;}
37pub trait TryGoToU64 {fn try_goto_u64(&self) -> Result<u64, ConversionError>;}
38pub trait TryGoToU128 {fn try_goto_u128(&self) -> Result<u128, ConversionError>;}
39pub trait TryGoToUsize {fn try_goto_usize(&self) -> Result<usize, ConversionError>;}
40pub trait TryGoToF32 {fn try_goto_f32(&self) -> Result<f32, ConversionError>;}
41pub trait TryGoToF64 {fn try_goto_f64(&self) -> Result<f64, ConversionError>;}
42impl GoToU8 for u8 {fn goto_u8(&self) -> u8 {*self as u8}}
46impl GoToU16 for u8 {fn goto_u16(&self) -> u16 {*self as u16}}
47impl GoToU32 for u8 {fn goto_u32(&self) -> u32 {*self as u32}}
48impl GoToU64 for u8 {fn goto_u64(&self) -> u64 {*self as u64}}
49impl GoToU128 for u8 {fn goto_u128(&self) -> u128 {*self as u128}}
50impl GoToUsize for u8 {fn goto_usize(&self) -> usize {*self as usize}}
51impl GoToF32 for u8 {fn goto_f32(&self) -> f32 {*self as f32}}
52impl GoToF64 for u8 {fn goto_f64(&self) -> f64 {*self as f64}}
53impl TryGoToU8 for u16 {
57 fn try_goto_u8(&self) -> Result<u8, ConversionError> {
58 if *self <= u8::MAX as u16 {Ok(*self as u8)}
59 else {Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} out of u8 range", self)))}
60 }
61}
62impl GoToU16 for u16 {fn goto_u16(&self) -> u16 {*self as u16}}
63impl GoToU32 for u16 {fn goto_u32(&self) -> u32 {*self as u32}}
64impl GoToU64 for u16 {fn goto_u64(&self) -> u64 {*self as u64}}
65impl GoToU128 for u16 {fn goto_u128(&self) -> u128 {*self as u128}}
66impl GoToUsize for u16 {fn goto_usize(&self) -> usize {*self as usize}}
67impl GoToF32 for u16 {fn goto_f32(&self) -> f32 {*self as f32}}
68impl GoToF64 for u16 {fn goto_f64(&self) -> f64 {*self as f64}}
69impl TryGoToU8 for u32 {
73 fn try_goto_u8(&self) -> Result<u8, ConversionError> {
74 if *self <= u8::MAX as u32 {Ok(*self as u8)}
75 else {Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} out of u8 range", self)))}
76 }
77}
78impl TryGoToU16 for u32 {
79 fn try_goto_u16(&self) -> Result<u16, ConversionError> {
80 if *self <= u16::MAX as u32 {Ok(*self as u16)}
81 else {Err(ConversionError::error("better-conversions::TryGoToU16::try_goto_u16", format!("{} out of u16 range", self)))}
82 }
83}
84impl GoToU32 for u32 {fn goto_u32(&self) -> u32 {*self as u32}}
85impl GoToU64 for u32 {fn goto_u64(&self) -> u64 {*self as u64}}
86impl GoToU128 for u32 {fn goto_u128(&self) -> u128 {*self as u128}}
87impl GoToUsize for u32 {fn goto_usize(&self) -> usize {*self as usize}}
88impl TryGoToF32 for u32 {
89 fn try_goto_f32(&self) -> Result<f32, ConversionError> {
90 let converted = *self as f32;
91 if converted as u32 == *self {Ok(converted)}
92 else {Err(ConversionError::error("better-conversions::TryGoToF32::try_goto_f32", format!("{} lost precision as a f32", self)))}
93 }
94}
95impl GoToF64 for u32 {fn goto_f64(&self) -> f64 {*self as f64}}
96impl TryGoToU8 for u64 {
100 fn try_goto_u8(&self) -> Result<u8, ConversionError> {
101 if *self <= u8::MAX as u64 {Ok(*self as u8)}
102 else {Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} out of u8 range", self)))}
103 }
104}
105impl TryGoToU16 for u64 {
106 fn try_goto_u16(&self) -> Result<u16, ConversionError> {
107 if *self <= u16::MAX as u64 {Ok(*self as u16)}
108 else {Err(ConversionError::error("better-conversions::TryGoToU16::try_goto_u16", format!("{} out of u16 range", self)))}
109 }
110}
111impl TryGoToU32 for u64 {
112 fn try_goto_u32(&self) -> Result<u32, ConversionError> {
113 if *self <= u32::MAX as u64 {Ok(*self as u32)}
114 else {Err(ConversionError::error("better-conversions::TryGoToU32::try_goto_u32", format!("{} out of u32 range", self)))}
115 }
116}
117impl GoToU64 for u64 {fn goto_u64(&self) -> u64 {*self as u64}}
118impl GoToU128 for u64 {fn goto_u128(&self) -> u128 {*self as u128}}
119impl TryGoToUsize for u64 {
120 fn try_goto_usize(&self) -> Result<usize, ConversionError> {
121 if *self <= usize::MAX as u64 {Ok(*self as usize)}
122 else {Err(ConversionError::error("better-conversions::TryGoToUsize::try_goto_usize", format!("{} out of usize range", self)))}
123 }
124}
125impl TryGoToF32 for u64 {
126 fn try_goto_f32(&self) -> Result<f32, ConversionError> {
127 let converted = *self as f32;
128 if converted as u64 == *self {Ok(converted)}
129 else {Err(ConversionError::error("better-conversions::TryGoToF32::try_goto_f32", format!("{} lost precision as a f32", self)))}
130 }
131}
132impl TryGoToF64 for u64 {
133 fn try_goto_f64(&self) -> Result<f64, ConversionError> {
134 let converted = *self as f64;
135 if converted as u64 == *self {Ok(converted)}
136 else {Err(ConversionError::error("better-conversions::TryGoToF64::try_goto_f64", format!("{} lost precision as a f64", self)))}
137 }
138}
139impl TryGoToU8 for u128 {
143 fn try_goto_u8(&self) -> Result<u8, ConversionError> {
144 if *self <= u8::MAX as u128 {Ok(*self as u8)}
145 else {Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} out of u8 range", self)))}
146 }
147}
148impl TryGoToU16 for u128 {
149 fn try_goto_u16(&self) -> Result<u16, ConversionError> {
150 if *self <= u16::MAX as u128 {Ok(*self as u16)}
151 else {Err(ConversionError::error("better-conversions::TryGoToU16::try_goto_u16", format!("{} out of u16 range", self)))}
152 }
153}
154impl TryGoToU32 for u128 {
155 fn try_goto_u32(&self) -> Result<u32, ConversionError> {
156 if *self <= u32::MAX as u128 {Ok(*self as u32)}
157 else {Err(ConversionError::error("better-conversions::TryGoToU32::try_goto_u32", format!("{} out of u32 range", self)))}
158 }
159}
160impl TryGoToU64 for u128 {
161 fn try_goto_u64(&self) -> Result<u64, ConversionError> {
162 if *self <= u64::MAX as u128 {Ok(*self as u64)}
163 else {Err(ConversionError::error("better-conversions::TryGoToU64::try_goto_u64", format!("{} out of u64 range", self)))}
164 }
165}
166impl GoToU128 for u128 {fn goto_u128(&self) -> u128 {*self as u128}}
167impl TryGoToUsize for u128 {
168 fn try_goto_usize(&self) -> Result<usize, ConversionError> {
169 if *self <= usize::MAX as u128 {Ok(*self as usize)}
170 else {Err(ConversionError::error("better-conversions::TryGoToUsize::try_goto_usize", format!("{} out of usize range", self)))}
171 }
172}
173impl TryGoToF32 for u128 {
174 fn try_goto_f32(&self) -> Result<f32, ConversionError> {
175 let converted = *self as f32;
176 if converted as u128 == *self {Ok(converted)}
177 else {Err(ConversionError::error("better-conversions::TryGoToF32::try_goto_f32", format!("{} lost precision as a f32", self)))}
178 }
179}
180impl TryGoToF64 for u128 {
181 fn try_goto_f64(&self) -> Result<f64, ConversionError> {
182 let converted = *self as f64;
183 if converted as u128 == *self {Ok(converted)}
184 else {Err(ConversionError::error("better-conversions::TryGoToF64::try_goto_f64", format!("{} lost precision as a f64", self)))}
185 }
186}
187impl TryGoToU8 for usize {
191 fn try_goto_u8(&self) -> Result<u8, ConversionError> {
192 if *self <= u8::MAX as usize { Ok(*self as u8) }
193 else { Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} out of u8 range", self))) }
194 }
195}
196impl TryGoToU16 for usize {
197 fn try_goto_u16(&self) -> Result<u16, ConversionError> {
198 if *self <= u16::MAX as usize { Ok(*self as u16) }
199 else { Err(ConversionError::error("better-conversions::TryGoToU16::try_goto_u16", format!("{} out of u16 range", self))) }
200 }
201}
202impl TryGoToU32 for usize {
203 fn try_goto_u32(&self) -> Result<u32, ConversionError> {
204 if *self <= u32::MAX as usize { Ok(*self as u32) }
205 else { Err(ConversionError::error("better-conversions::TryGoToU32::try_goto_u32", format!("{} out of u32 range", self))) }
206 }
207}
208impl TryGoToU64 for usize {
209 fn try_goto_u64(&self) -> Result<u64, ConversionError> {
210 if *self <= u64::MAX as usize { Ok(*self as u64) }
211 else { Err(ConversionError::error("better-conversions::TryGoToU64::try_goto_u64", format!("{} out of u64 range", self))) }
212 }
213}
214impl GoToU128 for usize { fn goto_u128(&self) -> u128 { *self as u128 } }
215impl GoToUsize for usize { fn goto_usize(&self) -> usize { *self } }
216impl TryGoToF32 for usize {
217 fn try_goto_f32(&self) -> Result<f32, ConversionError> {
218 let converted = *self as f32;
219 if converted as usize == *self { Ok(converted) }
220 else { Err(ConversionError::error("better-conversions::TryGoToF32::try_goto_f32", format!("{} lost precision as a f32", self))) }
221 }
222}
223impl TryGoToF64 for usize {
224 fn try_goto_f64(&self) -> Result<f64, ConversionError> {
225 let converted = *self as f64;
226 if converted as usize == *self { Ok(converted) }
227 else { Err(ConversionError::error("better-conversions::TryGoToF64::try_goto_f64", format!("{} lost precision as a f64", self))) }
228 }
229}
230impl TryGoToU8 for f32 {
234 fn try_goto_u8(&self) -> Result<u8, ConversionError> {
235 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} is not finite", self)));}
236 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} has a fractional", self)));}
237 if *self >= 0.0 && *self <= u8::MAX as f32 {Ok(*self as u8)}
238 else {Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} out of u8 range", self)))}
239 }
240}
241impl TryGoToU16 for f32 {
242 fn try_goto_u16(&self) -> Result<u16, ConversionError> {
243 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToU16::try_goto_u16", format!("{} is not finite", self)));}
244 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToU16::try_goto_u16", format!("{} has a fractional", self)));}
245 if *self >= 0.0 && *self <= u16::MAX as f32 {Ok(*self as u16)}
246 else {Err(ConversionError::error("better-conversions::TryGoToU16::try_goto_u16", format!("{} out of u16 range", self)))}
247 }
248}
249impl TryGoToU32 for f32 {
250 fn try_goto_u32(&self) -> Result<u32, ConversionError> {
251 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToU32::try_goto_u32", format!("{} is not finite", self)));}
252 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToU32::try_goto_u32", format!("{} has a fractional", self)));}
253 if *self >= 0.0 && *self <= u32::MAX as f32 {Ok(*self as u32)}
254 else {Err(ConversionError::error("better-conversions::TryGoToU32::try_goto_u32", format!("{} out of u32 range", self)))}
255 }
256}
257impl TryGoToU64 for f32 {
258 fn try_goto_u64(&self) -> Result<u64, ConversionError> {
259 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToU64::try_goto_u64", format!("{} is not finite", self)));}
260 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToU64::try_goto_u64", format!("{} has a fractional", self)));}
261 if *self >= 0.0 && *self <= u64::MAX as f32 {Ok(*self as u64)}
262 else {Err(ConversionError::error("better-conversions::TryGoToU64::try_goto_u64", format!("{} out of u64 range", self)))}
263 }
264}
265impl TryGoToU128 for f32 {
266 fn try_goto_u128(&self) -> Result<u128, ConversionError> {
267 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToU128::try_goto_u128", format!("{} is not finite", self)));}
268 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToU128::try_goto_u128", format!("{} has a fractional", self)));}
269 if *self >= 0.0 && *self <= u128::MAX as f32 {Ok(*self as u128)}
270 else {Err(ConversionError::error("better-conversions::TryGoToU128::try_goto_u128", format!("{} out of u128 range", self)))}
271 }
272}
273impl TryGoToUsize for f32 {
274 fn try_goto_usize(&self) -> Result<usize, ConversionError> {
275 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToUsize::try_goto_usize", format!("{} is not finite", self)));}
276 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToUsize::try_goto_usize", format!("{} has a fractional", self)));
277 }
278 if *self >= 0.0 && *self <= usize::MAX as f32 {Ok(*self as usize)}
279 else {Err(ConversionError::error("better-conversions::TryGoToUsize::try_goto_usize", format!("{} out of usize range", self)))}
280 }
281}
282impl GoToF32 for f32 {fn goto_f32(&self) -> f32 {*self as f32}}
283impl GoToF64 for f32 {fn goto_f64(&self) -> f64 {*self as f64}}
284impl TryGoToU8 for f64 {
288 fn try_goto_u8(&self) -> Result<u8, ConversionError> {
289 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} is not finite", self)));}
290 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} has a fractional", self)));}
291 if *self >= 0.0 && *self <= u8::MAX as f64 {Ok(*self as u8)}
292 else {Err(ConversionError::error("better-conversions::TryGoToU8::try_goto_u8", format!("{} out of u8 range", self)))}
293 }
294}
295impl TryGoToU16 for f64 {
296 fn try_goto_u16(&self) -> Result<u16, ConversionError> {
297 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToU16::try_goto_u16", format!("{} is not finite", self)));}
298 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToU16::try_goto_u16", format!("{} has a fractional", self)));}
299 if *self >= 0.0 && *self <= u16::MAX as f64 {Ok(*self as u16)}
300 else {Err(ConversionError::error("better-conversions::TryGoToU16::try_goto_u16", format!("{} out of u16 range", self)))}
301 }
302}
303impl TryGoToU32 for f64 {
304 fn try_goto_u32(&self) -> Result<u32, ConversionError> {
305 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToU32::try_goto_u32", format!("{} is not finite", self)));}
306 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToU32::try_goto_u32", format!("{} has a fractional", self)));}
307 if *self >= 0.0 && *self <= u32::MAX as f64 {Ok(*self as u32)}
308 else {Err(ConversionError::error("better-conversions::TryGoToU32::try_goto_u32", format!("{} out of u32 range", self)))}
309 }
310}
311impl TryGoToU64 for f64 {
312 fn try_goto_u64(&self) -> Result<u64, ConversionError> {
313 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToU64::try_goto_u64", format!("{} is not finite", self)));}
314 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToU64::try_goto_u64", format!("{} has a fractional", self)));}
315 if *self >= 0.0 && *self <= u64::MAX as f64 {Ok(*self as u64)}
316 else {Err(ConversionError::error("better-conversions::TryGoToU64::try_goto_u64", format!("{} out of u64 range", self)))}
317 }
318}
319impl TryGoToU128 for f64 {
320 fn try_goto_u128(&self) -> Result<u128, ConversionError> {
321 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToU128::try_goto_u128", format!("{} is not finite", self)));}
322 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToU128::try_goto_u128", format!("{} has a fractional", self)));}
323 if *self >= 0.0 && *self <= u128::MAX as f64 {Ok(*self as u128)}
324 else {Err(ConversionError::error("better-conversions::TryGoToU128::try_goto_u128", format!("{} out of u128 range", self)))}
325 }
326}
327impl TryGoToUsize for f64 {
328 fn try_goto_usize(&self) -> Result<usize, ConversionError> {
329 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToUsize::try_goto_usize", format!("{} is not finite", self)));}
330 if self.fract() != 0.0 {return Err(ConversionError::error("better-conversions::TryGoToUsize::try_goto_usize", format!("{} has a fractional", self)));}
331 if *self >= 0.0 && *self <= usize::MAX as f64 {Ok(*self as usize)}
332 else {Err(ConversionError::error("better-conversions::TryGoToUsize::try_goto_usize", format!("{} out of usize range", self)))}
333 }
334}
335impl TryGoToF32 for f64 {
336 fn try_goto_f32(&self) -> Result<f32, ConversionError> {
337 if !self.is_finite() {return Err(ConversionError::error("better-conversions::TryGoToF32::try_goto_f32", format!("{} is not finite", self)));}
338 if *self >= f32::MIN as f64 && *self <= f32::MAX as f64 {Ok(*self as f32)}
339 else {Err(ConversionError::error("better-conversions::TryGoToF32::try_goto_f32", format!("{} out of f32 range", self)))}
340 }
341}
342impl GoToF64 for f64 {fn goto_f64(&self) -> f64 {*self as f64}}
343