How convert string to integer with suffix type like "10i32"

I am trying to write a code parse string to integer

pub fn parse(s: &str) -> Option<i32>{
const NUMBERS: [&'static str; 12] = [
    "i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "isize", "usize", "f32", "f64",
];
for int in NUMBERS.iter() {
    match s.split(int).collect::<Vec<&str>>()[0].parse::<i32>() {
        Ok(o) => {
            println!("{}", o);
            return Some(o);
        }
        Err(_) => continue,
    }
}
None

}
but problem is i force str convert to i32 not the exactly type how write generic code can infer type from str

Before thinking about the technicalities of an implementation, let’s first think about the signature of such a “generic/general integer” parsing function:

  • input: &str;

  • output: Result<_, ParseError> for some defined ParseError (depending on the amount of information the error may carry).

Now, the main question is, what should _ be ? It cannot be i32, because "32_u32" cannot (and should not) be parsed as a i32. And the same reasoning applies for other numeric types.

This is a common issue with serialization, there needs to be some form of a dynamic type. For that, there are two tools at your disposal: an enum or a trait object (abstracting over the common behavior of all these numeric types. Given that the set of numeric types is known in advance, the enum should give a more flexible (albeit cumbersome) path).

enum:

enum ParsedInt {
     I8(i8),
     U8(u8),
     // ...
     I64(i64),
     U64(u64),
}
use self::ParsedInt::*;

This way, thanks to the (dynamic) tag / name of an enum, we are now capable of unifying all these numeric types into a single type.

Now, within your parsing logic, if, for instance, you encounter "xxx_i32", you know you have to try to parse "xxx" as a i32, and on success (let’s say we get x: i32), return Ok(I32(x)), etc.

7 Likes