rosu_map/util/
parse_number.rs1use std::num;
2
3pub const MAX_PARSE_VALUE: i32 = i32::MAX;
5
6pub trait ParseNumber: Sized {
8 fn parse(s: &str) -> Result<Self, ParseNumberError>;
10
11 fn parse_with_limits(s: &str, limit: Self) -> Result<Self, ParseNumberError>;
13}
14
15thiserror! {
16 #[derive(Debug)]
18 pub enum ParseNumberError {
19 #[error("invalid float")]
20 InvalidFloat(#[from] num::ParseFloatError),
21 #[error("invalid integer")]
22 InvalidInteger(#[from] num::ParseIntError),
23 #[error("not a number")]
24 NaN,
25 #[error("value is too high")]
26 NumberOverflow,
27 #[error("value is too low")]
28 NumberUnderflow,
29 }
30}
31
32impl ParseNumber for i32 {
33 fn parse(s: &str) -> Result<Self, ParseNumberError> {
34 Self::parse_with_limits(s, MAX_PARSE_VALUE)
35 }
36
37 fn parse_with_limits(s: &str, limit: Self) -> Result<Self, ParseNumberError> {
38 let n: Self = s.trim().parse()?;
39
40 if n < -limit {
41 Err(ParseNumberError::NumberUnderflow)
42 } else if n > limit {
43 Err(ParseNumberError::NumberOverflow)
44 } else {
45 Ok(n)
46 }
47 }
48}
49
50impl ParseNumber for f32 {
51 fn parse(s: &str) -> Result<Self, ParseNumberError> {
52 Self::parse_with_limits(s, MAX_PARSE_VALUE as Self)
53 }
54
55 fn parse_with_limits(s: &str, limit: Self) -> Result<Self, ParseNumberError> {
56 let n: Self = s.trim().parse()?;
57
58 if n < -limit {
59 Err(ParseNumberError::NumberUnderflow)
60 } else if n > limit {
61 Err(ParseNumberError::NumberOverflow)
62 } else if n.is_nan() {
63 Err(ParseNumberError::NaN)
64 } else {
65 Ok(n)
66 }
67 }
68}
69
70impl ParseNumber for f64 {
71 fn parse(s: &str) -> Result<Self, ParseNumberError> {
72 Self::parse_with_limits(s, Self::from(MAX_PARSE_VALUE))
73 }
74
75 fn parse_with_limits(s: &str, limit: Self) -> Result<Self, ParseNumberError> {
76 let n: Self = s.trim().parse()?;
77
78 if n < -limit {
79 Err(ParseNumberError::NumberUnderflow)
80 } else if n > limit {
81 Err(ParseNumberError::NumberOverflow)
82 } else if n.is_nan() {
83 Err(ParseNumberError::NaN)
84 } else {
85 Ok(n)
86 }
87 }
88}