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).
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.