Replace String with InputString in ParseIntError
Currently the `ParseIntError` contains an owned copy of the input string, this is causing us to have to use `alloc` everywhere. We already have a alloc-friendly string replacement type, the `InputString` - use it.
This commit is contained in:
parent
aa5c78430c
commit
3f2e760d1f
|
@ -6,7 +6,7 @@
|
|||
use alloc::{boxed::Box, string::String};
|
||||
use core::fmt;
|
||||
|
||||
use internals::write_err;
|
||||
use internals::error::InputString;
|
||||
|
||||
use crate::parse::ParseIntError;
|
||||
#[cfg(feature = "alloc")]
|
||||
|
@ -221,7 +221,7 @@ impl From<ParseError> for ParseTimeError {
|
|||
fn parser<T, E, S, F>(f: F) -> impl FnOnce(S) -> Result<T, E>
|
||||
where
|
||||
E: From<ParseError>,
|
||||
S: AsRef<str> + Into<String>,
|
||||
S: AsRef<str> + Into<InputString>,
|
||||
F: FnOnce(u32) -> Result<T, ConversionError>,
|
||||
{
|
||||
move |s| {
|
||||
|
@ -234,7 +234,7 @@ where
|
|||
fn parse_hex<T, E, S, F>(s: S, f: F) -> Result<T, E>
|
||||
where
|
||||
E: From<ParseError>,
|
||||
S: AsRef<str> + Into<String>,
|
||||
S: AsRef<str> + Into<InputString>,
|
||||
F: FnOnce(u32) -> Result<T, ConversionError>,
|
||||
{
|
||||
let n = i64::from_str_radix(parse::hex_remove_optional_prefix(s.as_ref()), 16)
|
||||
|
@ -310,7 +310,7 @@ enum ParseError {
|
|||
internals::impl_from_infallible!(ParseError);
|
||||
|
||||
impl ParseError {
|
||||
fn invalid_int<S: Into<String>>(s: S) -> impl FnOnce(core::num::ParseIntError) -> Self {
|
||||
fn invalid_int<S: Into<InputString>>(s: S) -> impl FnOnce(core::num::ParseIntError) -> Self {
|
||||
move |source| Self::ParseInt(ParseIntError { input: s.into(), bits: 32, is_signed: true , source })
|
||||
}
|
||||
|
||||
|
@ -327,13 +327,15 @@ impl ParseError {
|
|||
|
||||
match self {
|
||||
ParseInt(ParseIntError { input, bits: _, is_signed: _, source }) if *source.kind() == IntErrorKind::PosOverflow => {
|
||||
write!(f, "{} {} is above limit {}", subject, input, upper_bound)
|
||||
// Outputs "failed to parse <input_string> as absolute Height/Time (<subject> is above limit <upper_bound>)"
|
||||
write!(f, "{} ({} is above limit {})", input.display_cannot_parse("absolute Height/Time"), subject, upper_bound)
|
||||
}
|
||||
ParseInt(ParseIntError { input, bits: _, is_signed: _, source }) if *source.kind() == IntErrorKind::NegOverflow => {
|
||||
write!(f, "{} {} is below limit {}", subject, input, lower_bound)
|
||||
// Outputs "failed to parse <input_string> as absolute Height/Time (<subject> is below limit <lower_bound>)"
|
||||
write!(f, "{} ({} is below limit {})", input.display_cannot_parse("absolute Height/Time"), subject, lower_bound)
|
||||
}
|
||||
ParseInt(ParseIntError { input, bits: _, is_signed: _, source }) => {
|
||||
write_err!(f, "failed to parse {} as {}", input, subject; source)
|
||||
ParseInt(ParseIntError { input, bits: _, is_signed: _, source: _ }) => {
|
||||
write!(f, "{} ({})", input.display_cannot_parse("absolute Height/Time"), subject)
|
||||
}
|
||||
Conversion(value) if *value < i64::from(lower_bound) => {
|
||||
write!(f, "{} {} is below limit {}", subject, value, lower_bound)
|
||||
|
|
|
@ -7,6 +7,7 @@ use core::fmt;
|
|||
use core::str::FromStr;
|
||||
|
||||
use internals::write_err;
|
||||
use internals::error::InputString;
|
||||
|
||||
/// Error with rich context returned when a string can't be parsed as an integer.
|
||||
///
|
||||
|
@ -20,7 +21,7 @@ use internals::write_err;
|
|||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[non_exhaustive]
|
||||
pub struct ParseIntError {
|
||||
pub(crate) input: String,
|
||||
pub(crate) input: InputString,
|
||||
// for displaying - see Display impl with nice error message below
|
||||
pub(crate) bits: u8,
|
||||
// We could represent this as a single bit but it wouldn't actually derease the cost of moving
|
||||
|
@ -30,16 +31,10 @@ pub struct ParseIntError {
|
|||
pub(crate) source: core::num::ParseIntError,
|
||||
}
|
||||
|
||||
impl ParseIntError {
|
||||
/// Returns the input that was attempted to be parsed.
|
||||
pub fn input(&self) -> &str { &self.input }
|
||||
}
|
||||
|
||||
impl fmt::Display for ParseIntError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let signed = if self.is_signed { "signed" } else { "unsigned" };
|
||||
let n = if self.bits == 8 { "n" } else { "" };
|
||||
write_err!(f, "failed to parse '{}' as a{} {}-bit {} integer", self.input, n, self.bits, signed; self.source)
|
||||
write_err!(f, "{} ({}, {}-bit)", self.input.display_cannot_parse("integer"), signed, self.bits; self.source)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +69,7 @@ impl_integer!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128);
|
|||
///
|
||||
/// If the caller owns `String` or `Box<str>` which is not used later it's better to pass it as
|
||||
/// owned since it avoids allocation in error case.
|
||||
pub fn int<T: Integer, S: AsRef<str> + Into<String>>(s: S) -> Result<T, ParseIntError> {
|
||||
pub fn int<T: Integer, S: AsRef<str> + Into<InputString>>(s: S) -> Result<T, ParseIntError> {
|
||||
s.as_ref().parse().map_err(|error| {
|
||||
ParseIntError {
|
||||
input: s.into(),
|
||||
|
|
Loading…
Reference in New Issue