mirror of
https://github.com/uutils/coreutils.git
synced 2025-12-23 08:47:37 +00:00
uucore: num_parser: Copy PartialMatch String in ExtendedParserError
In one case, we'll need an actual owned String in PartialMatch, so it's easier to just use that. Removes a bunch of lifetime things in the code too.
This commit is contained in:
parent
5b6a617024
commit
9ddb8092e7
2 changed files with 201 additions and 140 deletions
|
|
@ -172,7 +172,7 @@ impl<'a> FormatArguments<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn extract_value<T: Default>(p: Result<T, ExtendedParserError<'_, T>>, input: &str) -> T {
|
||||
fn extract_value<T: Default>(p: Result<T, ExtendedParserError<T>>, input: &str) -> T {
|
||||
match p {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
|
|
|
|||
|
|
@ -109,12 +109,12 @@ impl Base {
|
|||
|
||||
/// Type returned if a number could not be parsed in its entirety
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ExtendedParserError<'a, T> {
|
||||
pub enum ExtendedParserError<T> {
|
||||
/// The input as a whole makes no sense
|
||||
NotNumeric,
|
||||
/// The beginning of the input made sense and has been parsed,
|
||||
/// while the remaining doesn't.
|
||||
PartialMatch(T, &'a str),
|
||||
PartialMatch(T, String),
|
||||
/// The value has overflowed the type storage. The returned value
|
||||
/// is saturated (e.g. positive or negative infinity, or min/max
|
||||
/// value for the integer type).
|
||||
|
|
@ -124,7 +124,7 @@ pub enum ExtendedParserError<'a, T> {
|
|||
Underflow(T),
|
||||
}
|
||||
|
||||
impl<'a, T> ExtendedParserError<'a, T>
|
||||
impl<T> ExtendedParserError<T>
|
||||
where
|
||||
T: Zero,
|
||||
{
|
||||
|
|
@ -143,12 +143,12 @@ where
|
|||
/// conversion.
|
||||
fn map<U>(
|
||||
self,
|
||||
f: impl FnOnce(T) -> Result<U, ExtendedParserError<'a, U>>,
|
||||
) -> ExtendedParserError<'a, U>
|
||||
f: impl FnOnce(T) -> Result<U, ExtendedParserError<U>>,
|
||||
) -> ExtendedParserError<U>
|
||||
where
|
||||
U: Zero,
|
||||
{
|
||||
fn extract<U>(v: Result<U, ExtendedParserError<'_, U>>) -> U
|
||||
fn extract<U>(v: Result<U, ExtendedParserError<U>>) -> U
|
||||
where
|
||||
U: Zero,
|
||||
{
|
||||
|
|
@ -172,15 +172,15 @@ where
|
|||
/// and `f64` float, where octal and binary formats are not allowed.
|
||||
pub trait ExtendedParser {
|
||||
// We pick a hopefully different name for our parser, to avoid clash with standard traits.
|
||||
fn extended_parse(input: &str) -> Result<Self, ExtendedParserError<'_, Self>>
|
||||
fn extended_parse(input: &str) -> Result<Self, ExtendedParserError<Self>>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
impl ExtendedParser for i64 {
|
||||
/// Parse a number as i64. No fractional part is allowed.
|
||||
fn extended_parse(input: &str) -> Result<i64, ExtendedParserError<'_, i64>> {
|
||||
fn into_i64<'a>(ebd: ExtendedBigDecimal) -> Result<i64, ExtendedParserError<'a, i64>> {
|
||||
fn extended_parse(input: &str) -> Result<i64, ExtendedParserError<i64>> {
|
||||
fn into_i64(ebd: ExtendedBigDecimal) -> Result<i64, ExtendedParserError<i64>> {
|
||||
match ebd {
|
||||
ExtendedBigDecimal::BigDecimal(bd) => {
|
||||
let (digits, scale) = bd.into_bigint_and_scale();
|
||||
|
|
@ -214,8 +214,8 @@ impl ExtendedParser for i64 {
|
|||
|
||||
impl ExtendedParser for u64 {
|
||||
/// Parse a number as u64. No fractional part is allowed.
|
||||
fn extended_parse(input: &str) -> Result<u64, ExtendedParserError<'_, u64>> {
|
||||
fn into_u64<'a>(ebd: ExtendedBigDecimal) -> Result<u64, ExtendedParserError<'a, u64>> {
|
||||
fn extended_parse(input: &str) -> Result<u64, ExtendedParserError<u64>> {
|
||||
fn into_u64(ebd: ExtendedBigDecimal) -> Result<u64, ExtendedParserError<u64>> {
|
||||
match ebd {
|
||||
ExtendedBigDecimal::BigDecimal(bd) => {
|
||||
let (digits, scale) = bd.into_bigint_and_scale();
|
||||
|
|
@ -251,8 +251,8 @@ impl ExtendedParser for u64 {
|
|||
|
||||
impl ExtendedParser for f64 {
|
||||
/// Parse a number as f64
|
||||
fn extended_parse(input: &str) -> Result<f64, ExtendedParserError<'_, f64>> {
|
||||
fn into_f64<'a>(ebd: ExtendedBigDecimal) -> Result<f64, ExtendedParserError<'a, f64>> {
|
||||
fn extended_parse(input: &str) -> Result<f64, ExtendedParserError<f64>> {
|
||||
fn into_f64(ebd: ExtendedBigDecimal) -> Result<f64, ExtendedParserError<f64>> {
|
||||
// TODO: _Some_ of this is generic, so this should probably be implemented as an ExtendedBigDecimal trait (ToPrimitive).
|
||||
let v = match ebd {
|
||||
ExtendedBigDecimal::BigDecimal(bd) => {
|
||||
|
|
@ -285,7 +285,7 @@ impl ExtendedParser for ExtendedBigDecimal {
|
|||
/// Parse a number as an ExtendedBigDecimal
|
||||
fn extended_parse(
|
||||
input: &str,
|
||||
) -> Result<ExtendedBigDecimal, ExtendedParserError<'_, ExtendedBigDecimal>> {
|
||||
) -> Result<ExtendedBigDecimal, ExtendedParserError<ExtendedBigDecimal>> {
|
||||
parse(input, ParseTarget::Decimal, &[])
|
||||
}
|
||||
}
|
||||
|
|
@ -349,11 +349,11 @@ fn parse_suffix_multiplier<'a>(str: &'a str, allowed_suffixes: &[(char, u32)]) -
|
|||
(1, str)
|
||||
}
|
||||
|
||||
fn parse_special_value<'a>(
|
||||
input: &'a str,
|
||||
fn parse_special_value(
|
||||
input: &str,
|
||||
negative: bool,
|
||||
allowed_suffixes: &[(char, u32)],
|
||||
) -> Result<ExtendedBigDecimal, ExtendedParserError<'a, ExtendedBigDecimal>> {
|
||||
) -> Result<ExtendedBigDecimal, ExtendedParserError<ExtendedBigDecimal>> {
|
||||
let input_lc = input.to_ascii_lowercase();
|
||||
|
||||
// Array of ("String to match", return value when sign positive, when sign negative)
|
||||
|
|
@ -376,7 +376,7 @@ fn parse_special_value<'a>(
|
|||
return if rest.is_empty() {
|
||||
Ok(special)
|
||||
} else {
|
||||
Err(ExtendedParserError::PartialMatch(special, rest))
|
||||
Err(ExtendedParserError::PartialMatch(special, rest.to_string()))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -386,7 +386,7 @@ fn parse_special_value<'a>(
|
|||
|
||||
/// Underflow/Overflow errors always contain 0 or infinity.
|
||||
/// overflow: true for overflow, false for underflow.
|
||||
fn make_error<'a>(overflow: bool, negative: bool) -> ExtendedParserError<'a, ExtendedBigDecimal> {
|
||||
fn make_error(overflow: bool, negative: bool) -> ExtendedParserError<ExtendedBigDecimal> {
|
||||
let mut v = if overflow {
|
||||
ExtendedBigDecimal::Infinity
|
||||
} else {
|
||||
|
|
@ -468,13 +468,13 @@ fn pow_with_context(bd: &BigDecimal, exp: i64, ctx: &Context) -> BigDecimal {
|
|||
}
|
||||
|
||||
/// Construct an [`ExtendedBigDecimal`] based on parsed data
|
||||
fn construct_extended_big_decimal<'a>(
|
||||
fn construct_extended_big_decimal(
|
||||
digits: BigUint,
|
||||
negative: bool,
|
||||
base: Base,
|
||||
scale: i64,
|
||||
exponent: BigInt,
|
||||
) -> Result<ExtendedBigDecimal, ExtendedParserError<'a, ExtendedBigDecimal>> {
|
||||
) -> Result<ExtendedBigDecimal, ExtendedParserError<ExtendedBigDecimal>> {
|
||||
if digits == BigUint::zero() {
|
||||
// Return return 0 if the digits are zero. In particular, we do not ever
|
||||
// return Overflow/Underflow errors in that case.
|
||||
|
|
@ -541,11 +541,11 @@ pub(crate) enum ParseTarget {
|
|||
Duration,
|
||||
}
|
||||
|
||||
pub(crate) fn parse<'a>(
|
||||
input: &'a str,
|
||||
pub(crate) fn parse(
|
||||
input: &str,
|
||||
target: ParseTarget,
|
||||
allowed_suffixes: &[(char, u32)],
|
||||
) -> Result<ExtendedBigDecimal, ExtendedParserError<'a, ExtendedBigDecimal>> {
|
||||
) -> Result<ExtendedBigDecimal, ExtendedParserError<ExtendedBigDecimal>> {
|
||||
// Note: literals with ' and " prefixes are parsed earlier on in argument parsing,
|
||||
// before UTF-8 conversion.
|
||||
|
||||
|
|
@ -604,7 +604,7 @@ pub(crate) fn parse<'a>(
|
|||
} else {
|
||||
ExtendedBigDecimal::zero()
|
||||
};
|
||||
return Err(ExtendedParserError::PartialMatch(ebd, partial));
|
||||
return Err(ExtendedParserError::PartialMatch(ebd, partial.to_string()));
|
||||
}
|
||||
|
||||
return if target == ParseTarget::Integral {
|
||||
|
|
@ -628,7 +628,7 @@ pub(crate) fn parse<'a>(
|
|||
} else {
|
||||
Err(ExtendedParserError::PartialMatch(
|
||||
ebd_result.unwrap_or_else(|e| e.extract()),
|
||||
rest,
|
||||
rest.to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
@ -674,14 +674,14 @@ mod tests {
|
|||
u64::extended_parse(""),
|
||||
Err(ExtendedParserError::NotNumeric)
|
||||
));
|
||||
assert!(matches!(
|
||||
assert_eq!(
|
||||
u64::extended_parse("123.15"),
|
||||
Err(ExtendedParserError::PartialMatch(123, ".15"))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(123, ".15".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
u64::extended_parse("123e10"),
|
||||
Err(ExtendedParserError::PartialMatch(123, "e10"))
|
||||
));
|
||||
Err(ExtendedParserError::PartialMatch(123, "e10".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -695,18 +695,18 @@ mod tests {
|
|||
));
|
||||
assert_eq!(Ok(i64::MAX), i64::extended_parse(&format!("{}", i64::MAX)));
|
||||
assert_eq!(Ok(i64::MIN), i64::extended_parse(&format!("{}", i64::MIN)));
|
||||
assert!(matches!(
|
||||
assert_eq!(
|
||||
i64::extended_parse(&format!("{}", u64::MAX)),
|
||||
Err(ExtendedParserError::Overflow(i64::MAX))
|
||||
));
|
||||
);
|
||||
assert!(matches!(
|
||||
i64::extended_parse(&format!("{}", i64::MAX as u64 + 1)),
|
||||
Err(ExtendedParserError::Overflow(i64::MAX))
|
||||
));
|
||||
assert!(matches!(
|
||||
assert_eq!(
|
||||
i64::extended_parse("-123e10"),
|
||||
Err(ExtendedParserError::PartialMatch(-123, "e10"))
|
||||
));
|
||||
Err(ExtendedParserError::PartialMatch(-123, "e10".to_string()))
|
||||
);
|
||||
assert!(matches!(
|
||||
i64::extended_parse(&format!("{}", -(u64::MAX as i128))),
|
||||
Err(ExtendedParserError::Overflow(i64::MIN))
|
||||
|
|
@ -758,20 +758,34 @@ mod tests {
|
|||
Ok(0.15),
|
||||
f64::extended_parse(".150000000000000000000000000231313")
|
||||
);
|
||||
assert!(matches!(f64::extended_parse("123.15e"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "e")) if f == 123.15));
|
||||
assert!(matches!(f64::extended_parse("123.15E"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "E")) if f == 123.15));
|
||||
assert!(matches!(f64::extended_parse("123.15e-"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "e-")) if f == 123.15));
|
||||
assert!(matches!(f64::extended_parse("123.15e+"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "e+")) if f == 123.15));
|
||||
assert!(matches!(f64::extended_parse("123.15e."),
|
||||
Err(ExtendedParserError::PartialMatch(f, "e.")) if f == 123.15));
|
||||
assert!(matches!(f64::extended_parse("1.2.3"),
|
||||
Err(ExtendedParserError::PartialMatch(f, ".3")) if f == 1.2));
|
||||
assert!(matches!(f64::extended_parse("123.15p5"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "p5")) if f == 123.15));
|
||||
assert_eq!(
|
||||
f64::extended_parse("123.15e"),
|
||||
Err(ExtendedParserError::PartialMatch(123.15, "e".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("123.15E"),
|
||||
Err(ExtendedParserError::PartialMatch(123.15, "E".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("123.15e-"),
|
||||
Err(ExtendedParserError::PartialMatch(123.15, "e-".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("123.15e+"),
|
||||
Err(ExtendedParserError::PartialMatch(123.15, "e+".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("123.15e."),
|
||||
Err(ExtendedParserError::PartialMatch(123.15, "e.".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("1.2.3"),
|
||||
Err(ExtendedParserError::PartialMatch(1.2, ".3".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("123.15p5"),
|
||||
Err(ExtendedParserError::PartialMatch(123.15, "p5".to_string()))
|
||||
);
|
||||
// Minus zero. 0.0 == -0.0 so we explicitly check the sign.
|
||||
assert_eq!(Ok(0.0), f64::extended_parse("-0.0"));
|
||||
assert!(f64::extended_parse("-0.0").unwrap().is_sign_negative());
|
||||
|
|
@ -794,10 +808,20 @@ mod tests {
|
|||
assert!(f64::extended_parse("nan").unwrap().is_sign_positive());
|
||||
assert!(f64::extended_parse("NAN").unwrap().is_nan());
|
||||
assert!(f64::extended_parse("NAN").unwrap().is_sign_positive());
|
||||
assert!(matches!(f64::extended_parse("-infinit"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "init")) if f == f64::NEG_INFINITY));
|
||||
assert!(matches!(f64::extended_parse("-infinity00"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "00")) if f == f64::NEG_INFINITY));
|
||||
assert_eq!(
|
||||
f64::extended_parse("-infinit"),
|
||||
Err(ExtendedParserError::PartialMatch(
|
||||
f64::NEG_INFINITY,
|
||||
"init".to_string()
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("-infinity00"),
|
||||
Err(ExtendedParserError::PartialMatch(
|
||||
f64::NEG_INFINITY,
|
||||
"00".to_string()
|
||||
))
|
||||
);
|
||||
assert!(f64::extended_parse(&format!("{}", u64::MAX)).is_ok());
|
||||
assert!(f64::extended_parse(&format!("{}", i64::MIN)).is_ok());
|
||||
|
||||
|
|
@ -982,14 +1006,22 @@ mod tests {
|
|||
// but we can check that the number still gets parsed properly: 0x0.8e5 is 0x8e5 / 16**3
|
||||
assert_eq!(Ok(0.555908203125), f64::extended_parse("0x0.8e5"));
|
||||
|
||||
assert!(matches!(f64::extended_parse("0x0.1p"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "p")) if f == 0.0625));
|
||||
assert!(matches!(f64::extended_parse("0x0.1p-"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "p-")) if f == 0.0625));
|
||||
assert!(matches!(f64::extended_parse("0x.1p+"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "p+")) if f == 0.0625));
|
||||
assert!(matches!(f64::extended_parse("0x.1p."),
|
||||
Err(ExtendedParserError::PartialMatch(f, "p.")) if f == 0.0625));
|
||||
assert_eq!(
|
||||
f64::extended_parse("0x0.1p"),
|
||||
Err(ExtendedParserError::PartialMatch(0.0625, "p".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("0x0.1p-"),
|
||||
Err(ExtendedParserError::PartialMatch(0.0625, "p-".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("0x.1p+"),
|
||||
Err(ExtendedParserError::PartialMatch(0.0625, "p+".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("0x.1p."),
|
||||
Err(ExtendedParserError::PartialMatch(0.0625, "p.".to_string()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Ok(ExtendedBigDecimal::BigDecimal(
|
||||
|
|
@ -1049,40 +1081,58 @@ mod tests {
|
|||
));
|
||||
|
||||
// Not actually hex numbers, but the prefixes look like it.
|
||||
assert!(matches!(f64::extended_parse("0x"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "x")) if f == 0.0));
|
||||
assert!(matches!(f64::extended_parse("0x."),
|
||||
Err(ExtendedParserError::PartialMatch(f, "x.")) if f == 0.0));
|
||||
assert!(matches!(f64::extended_parse("0xp"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "xp")) if f == 0.0));
|
||||
assert!(matches!(f64::extended_parse("0xp-2"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "xp-2")) if f == 0.0));
|
||||
assert!(matches!(f64::extended_parse("0x.p-2"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "x.p-2")) if f == 0.0));
|
||||
assert!(matches!(f64::extended_parse("0X"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "X")) if f == 0.0));
|
||||
assert!(matches!(f64::extended_parse("-0x"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "x")) if f == -0.0));
|
||||
assert!(matches!(f64::extended_parse("+0x"),
|
||||
Err(ExtendedParserError::PartialMatch(f, "x")) if f == 0.0));
|
||||
assert!(matches!(f64::extended_parse("-0x."),
|
||||
Err(ExtendedParserError::PartialMatch(f, "x.")) if f == -0.0));
|
||||
assert!(matches!(
|
||||
assert_eq!(
|
||||
f64::extended_parse("0x"),
|
||||
Err(ExtendedParserError::PartialMatch(0.0, "x".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("0x."),
|
||||
Err(ExtendedParserError::PartialMatch(0.0, "x.".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("0xp"),
|
||||
Err(ExtendedParserError::PartialMatch(0.0, "xp".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("0xp-2"),
|
||||
Err(ExtendedParserError::PartialMatch(0.0, "xp-2".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("0x.p-2"),
|
||||
Err(ExtendedParserError::PartialMatch(0.0, "x.p-2".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("0X"),
|
||||
Err(ExtendedParserError::PartialMatch(0.0, "X".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("-0x"),
|
||||
Err(ExtendedParserError::PartialMatch(0.0, "x".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("+0x"),
|
||||
Err(ExtendedParserError::PartialMatch(0.0, "x".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("-0x."),
|
||||
Err(ExtendedParserError::PartialMatch(-0.0, "x.".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
u64::extended_parse("0x"),
|
||||
Err(ExtendedParserError::PartialMatch(0, "x"))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(0, "x".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
u64::extended_parse("-0x"),
|
||||
Err(ExtendedParserError::PartialMatch(0, "x"))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(0, "x".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
i64::extended_parse("0x"),
|
||||
Err(ExtendedParserError::PartialMatch(0, "x"))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(0, "x".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
i64::extended_parse("-0x"),
|
||||
Err(ExtendedParserError::PartialMatch(0, "x"))
|
||||
));
|
||||
Err(ExtendedParserError::PartialMatch(0, "x".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -1093,18 +1143,18 @@ mod tests {
|
|||
assert_eq!(Ok(-0o123), i64::extended_parse("-0123"));
|
||||
assert_eq!(Ok(0o123), u64::extended_parse("00123"));
|
||||
assert_eq!(Ok(0), u64::extended_parse("00"));
|
||||
assert!(matches!(
|
||||
assert_eq!(
|
||||
u64::extended_parse("008"),
|
||||
Err(ExtendedParserError::PartialMatch(0, "8"))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(0, "8".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
u64::extended_parse("08"),
|
||||
Err(ExtendedParserError::PartialMatch(0, "8"))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(0, "8".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
u64::extended_parse("0."),
|
||||
Err(ExtendedParserError::PartialMatch(0, "."))
|
||||
));
|
||||
Err(ExtendedParserError::PartialMatch(0, ".".to_string()))
|
||||
);
|
||||
|
||||
// No float tests, leading zeros get parsed as decimal anyway.
|
||||
}
|
||||
|
|
@ -1116,51 +1166,62 @@ mod tests {
|
|||
assert_eq!(Ok(0b1011), u64::extended_parse("+0b1011"));
|
||||
assert_eq!(Ok(-0b1011), i64::extended_parse("-0b1011"));
|
||||
|
||||
assert!(matches!(
|
||||
assert_eq!(
|
||||
u64::extended_parse("0b"),
|
||||
Err(ExtendedParserError::PartialMatch(0, "b"))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(0, "b".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
u64::extended_parse("0b."),
|
||||
Err(ExtendedParserError::PartialMatch(0, "b."))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(0, "b.".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
u64::extended_parse("-0b"),
|
||||
Err(ExtendedParserError::PartialMatch(0, "b"))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(0, "b".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
i64::extended_parse("0b"),
|
||||
Err(ExtendedParserError::PartialMatch(0, "b"))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(0, "b".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
i64::extended_parse("-0b"),
|
||||
Err(ExtendedParserError::PartialMatch(0, "b"))
|
||||
));
|
||||
Err(ExtendedParserError::PartialMatch(0, "b".to_string()))
|
||||
);
|
||||
|
||||
// Binary not allowed for floats
|
||||
assert!(matches!(
|
||||
assert_eq!(
|
||||
f64::extended_parse("0b100"),
|
||||
Err(ExtendedParserError::PartialMatch(0f64, "b100"))
|
||||
));
|
||||
assert!(matches!(
|
||||
Err(ExtendedParserError::PartialMatch(0f64, "b100".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
f64::extended_parse("0b100.1"),
|
||||
Err(ExtendedParserError::PartialMatch(0f64, "b100.1"))
|
||||
));
|
||||
Err(ExtendedParserError::PartialMatch(
|
||||
0f64,
|
||||
"b100.1".to_string()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(match ExtendedBigDecimal::extended_parse("0b100.1") {
|
||||
Err(ExtendedParserError::PartialMatch(ebd, "b100.1")) =>
|
||||
ebd == ExtendedBigDecimal::zero(),
|
||||
_ => false,
|
||||
});
|
||||
assert_eq!(
|
||||
ExtendedBigDecimal::extended_parse("0b100.1"),
|
||||
Err(ExtendedParserError::PartialMatch(
|
||||
ExtendedBigDecimal::zero(),
|
||||
"b100.1".to_string()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(match ExtendedBigDecimal::extended_parse("0b") {
|
||||
Err(ExtendedParserError::PartialMatch(ebd, "b")) => ebd == ExtendedBigDecimal::zero(),
|
||||
_ => false,
|
||||
});
|
||||
assert!(match ExtendedBigDecimal::extended_parse("0b.") {
|
||||
Err(ExtendedParserError::PartialMatch(ebd, "b.")) => ebd == ExtendedBigDecimal::zero(),
|
||||
_ => false,
|
||||
});
|
||||
assert_eq!(
|
||||
ExtendedBigDecimal::extended_parse("0b"),
|
||||
Err(ExtendedParserError::PartialMatch(
|
||||
ExtendedBigDecimal::zero(),
|
||||
"b".to_string()
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
ExtendedBigDecimal::extended_parse("0b."),
|
||||
Err(ExtendedParserError::PartialMatch(
|
||||
ExtendedBigDecimal::zero(),
|
||||
"b.".to_string()
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -1173,15 +1234,15 @@ mod tests {
|
|||
|
||||
// Ensure that trailing whitespace is still a partial match
|
||||
assert_eq!(
|
||||
Err(ExtendedParserError::PartialMatch(6, " ")),
|
||||
Err(ExtendedParserError::PartialMatch(6, " ".to_string())),
|
||||
u64::extended_parse("0x6 ")
|
||||
);
|
||||
assert_eq!(
|
||||
Err(ExtendedParserError::PartialMatch(7, "\t")),
|
||||
Err(ExtendedParserError::PartialMatch(7, "\t".to_string())),
|
||||
u64::extended_parse("0x7\t")
|
||||
);
|
||||
assert_eq!(
|
||||
Err(ExtendedParserError::PartialMatch(8, "\n")),
|
||||
Err(ExtendedParserError::PartialMatch(8, "\n".to_string())),
|
||||
u64::extended_parse("0x8\n")
|
||||
);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue