use crate::decoder::Decode;
use crate::errors::ParseResult;
use crate::numbers::{NumberParser, Radix};
use crate::{parse_from_string, ParserCore};
fn test_str(string: &str) -> ParserCore {
let decoder = Decode::from_string(string);
ParserCore::new("<string>", decoder)
}
#[test]
fn signed_ok() -> ParseResult<()> {
let mut numpar = NumberParser::new();
numpar.settings.permit_underscores = true;
let text_in = " -12_986 65_536 -16444 -1 0 0_0";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_i128(&mut parser)?, -12986);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_i128(&mut parser)?, 65536);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_i64(&mut parser)?, -16444);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_i64(&mut parser)?, -1);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_i128(&mut parser)?, 0);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_i64(&mut parser)?, 0);
let text_in = "-170_141_183_460_469_231_731_687_303_715_884_105_728";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert_eq!(
numpar.parse_i128(&mut parser)?,
-170_141_183_460_469_231_731_687_303_715_884_105_728
);
let text_in = "170_141_183_460_469_231_731_687_303_715_884_105_727";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert_eq!(
numpar.parse_i128(&mut parser)?,
170_141_183_460_469_231_731_687_303_715_884_105_727
);
numpar.settings.permit_underscores = false;
let text_in = "170141183460469231731687303715884105727";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert_eq!(
numpar.parse_i128(&mut parser)?,
170_141_183_460_469_231_731_687_303_715_884_105_727
);
Ok(())
}
#[test]
fn unsigned_ok() -> ParseResult<()> {
let mut numpar = NumberParser::new();
numpar.settings.permit_underscores = true;
let text_in = " 12_986 65_536 16444 1 0 0_0";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_u128(&mut parser)?, 12986);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_u64(&mut parser)?, 65536);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_u128(&mut parser)?, 16444);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_u64(&mut parser)?, 1);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_u128(&mut parser)?, 0);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_u64(&mut parser)?, 0);
let text_in = "340_282_366_920_938_463_463_374_607_431_768_211_456";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert!(numpar.parse_u128(&mut parser).is_err());
numpar.settings.permit_underscores = false;
let text_in = "340282366920938463463374607431768211456";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert!(numpar.parse_u128(&mut parser).is_err());
Ok(())
}
#[test]
fn signed_err() -> ParseResult<()> {
let mut numpar = NumberParser::new();
numpar.settings.permit_underscores = true;
let text_in = "";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert!(numpar.parse_i128(&mut parser).is_err());
let text_in = "A";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert!(numpar.parse_i128(&mut parser).is_err());
let text_in = "999_999_999_999_999_999_999_999_999_999_999_999_999";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert!(numpar.parse_i128(&mut parser).is_err());
let text_in = "170_141_183_460_469_231_731_687_303_715_884_105_728";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert!(numpar.parse_i64(&mut parser).is_err());
Ok(())
}
#[test]
fn unsigned_err() -> ParseResult<()> {
let mut numpar = NumberParser::new();
numpar.settings.permit_underscores = true;
let text_in = "";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert!(numpar.parse_u128(&mut parser).is_err());
let text_in = "A";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert!(numpar.parse_u128(&mut parser).is_err());
let text_in = "999_999_999_999_999_999_999_999_999_999_999_999_999";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert!(numpar.parse_u128(&mut parser).is_err());
let text_in = "340_282_366_920_938_463_463_374_607_431_768_211_456";
let mut parser = test_str(text_in);
let _ = parser.consume_ws_only();
assert!(numpar.parse_u64(&mut parser).is_err());
Ok(())
}
#[test]
fn reject_test() {
assert!(parse_from_string("0o10480").parse_i64().is_err());
assert!(parse_from_string("0o10480").parse_u64().is_err());
assert!(parse_from_string("0o").parse_i64().is_err());
assert!(parse_from_string("0o").parse_u64().is_err());
}
#[test]
fn radix_strings() {
assert_eq!(Radix::Binary.to_string(), "Binary");
assert_eq!(Radix::Octal.to_string(), "Octal");
assert_eq!(Radix::Decimal.to_string(), "Decimal");
assert_eq!(Radix::Hexadecimal.to_string(), "Hexadecimal");
assert_eq!(format!("{:?}", Radix::Hexadecimal), "Radix::Hexadecimal");
assert_eq!(format!("{:?}", Radix::Decimal), "Radix::Decimal");
assert_eq!(format!("{:?}", Radix::Octal), "Radix::Octal");
assert_eq!(format!("{:?}", Radix::Binary), "Radix::Binary");
}
#[test]
fn radices() -> ParseResult<()> {
let numpar = NumberParser::new();
let text_in = "0xff 0xff_ff -0xfff_f 0b10110 -0x000_1 0o21 -0o21";
let mut parser = test_str(text_in);
assert_eq!(numpar.parse_i128(&mut parser)?, 0xff);
parser.consume_ws_only();
assert_eq!(numpar.parse_i64(&mut parser)?, 0xffff);
parser.consume_ws_only();
assert_eq!(numpar.parse_i128(&mut parser)?, -0xffff);
parser.consume_ws_only();
assert_eq!(parser.peek_n(7), "0b10110");
assert_eq!(numpar.parse_i64(&mut parser)?, 0b10110);
parser.consume_ws_only();
assert_eq!(numpar.parse_i128(&mut parser)?, -0x1);
parser.consume_ws_only();
assert_eq!(numpar.parse_i64(&mut parser)?, 0o21);
parser.consume_ws_only();
assert_eq!(numpar.parse_i128(&mut parser)?, -0o21);
parser.consume_ws_only();
let text_in = "0xff 0xff_ff 0xfff_f 0b10110 0x000_1 0o210";
let mut parser = test_str(text_in);
assert_eq!(numpar.parse_u128(&mut parser)?, 0xff);
parser.consume_ws_only();
assert_eq!(numpar.parse_u64(&mut parser)?, 0xffff);
parser.consume_ws_only();
assert_eq!(numpar.parse_u128(&mut parser)?, 0xffff);
parser.consume_ws_only();
assert_eq!(parser.peek_n(7), "0b10110");
assert_eq!(numpar.parse_u64(&mut parser)?, 0b10110);
parser.consume_ws_only();
assert_eq!(numpar.parse_u128(&mut parser)?, 0x1);
parser.consume_ws_only();
assert_eq!(numpar.parse_u64(&mut parser)?, 0o210);
parser.consume_ws_only();
let text_in = "ff ff_ff -fff_f 10110 -000_1 21 -21 +17";
let mut parser = test_str(text_in);
assert_eq!(
numpar.parse_u128_radix(&mut parser, Radix::Hexadecimal)?,
0xff
);
let _ = parser.consume_ws_only();
assert_eq!(
numpar.parse_u64_radix(&mut parser, Radix::Hexadecimal)?,
0xffff
);
let _ = parser.consume_ws_only();
assert_eq!(
numpar.parse_i128_radix(&mut parser, Radix::Hexadecimal)?,
-0xffff
);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_i64_radix(&mut parser, Radix::Binary)?, 0b10110);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_i128_radix(&mut parser, Radix::Binary)?, -0b1);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_u128_radix(&mut parser, Radix::Octal)?, 0o21);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_i128_radix(&mut parser, Radix::Octal)?, -0o21);
let _ = parser.consume_ws_only();
assert_eq!(numpar.parse_i128_radix(&mut parser, Radix::Octal)?, 0o17);
Ok(())
}
#[test]
fn floats_1() -> ParseResult<()> {
let numpar = NumberParser::new();
let text_in = "12 12e2 -12 -12e2 12e-2 -12e-2 12p-2 -12p-2 12e+2";
let mut parser = test_str(text_in);
assert_eq!(numpar.parse_f64_decimal(&mut parser)?, 12.0);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, 1200.0);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64_decimal(&mut parser)?, -12.0);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64_decimal(&mut parser)?, -1200.0);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, 0.12);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, -0.12);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, 0.12);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, -0.12);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, 1200.0);
parser.consume_ws_only();
let text_in = "0b0.1 0o0.4 0.5 0x.8";
let mut parser = test_str(text_in);
assert_eq!(numpar.parse_f64(&mut parser)?, 0.5);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, 0.5);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, 0.5);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, 0.5);
parser.consume_ws_only();
Ok(())
}
#[test]
fn floats_2() -> ParseResult<()> {
let numpar = NumberParser::new();
let text_in = "0x0.400_000_000_000_000";
let mut parser = test_str(text_in);
assert_eq!(numpar.parse_f64(&mut parser)?, 0.25);
parser.consume_ws_only();
let text_in = "0x00006.5p-3";
let mut parser = test_str(text_in);
assert_eq!(numpar.parse_f64(&mut parser)?, 0.001_541_137_695_312_5);
parser.consume_ws_only();
let text_in = "0x6.5p-9_999_999_999";
let mut parser = test_str(text_in);
assert!(numpar.parse_f64(&mut parser).is_err());
parser.consume_ws_only();
let text_in = "0x.p2";
let mut parser = test_str(text_in);
assert!(numpar.parse_f64(&mut parser).is_err());
parser.consume_ws_only();
Ok(())
}
#[test]
fn floats_3() -> ParseResult<()> {
let numpar = NumberParser::new();
let text_in = "inf -inf infinity nan";
let mut parser = test_str(text_in);
assert_eq!(numpar.parse_f64(&mut parser)?, f64::INFINITY);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, -f64::INFINITY);
parser.consume_ws_only();
assert_eq!(numpar.parse_f64(&mut parser)?, f64::INFINITY);
parser.consume_ws_only();
assert!(numpar.parse_f64(&mut parser)?.is_nan());
parser.consume_ws_only();
Ok(())
}
#[test]
fn test_radix() {
assert_eq!(Radix::Hexadecimal.value(), 16);
assert_eq!(Radix::Decimal.value(), 10);
assert_eq!(Radix::Octal.value(), 8);
assert_eq!(Radix::Binary.value(), 2);
assert_eq!(Radix::Hexadecimal.to_string(), "Hexadecimal");
assert_eq!(Radix::Decimal.to_string(), "Decimal");
assert_eq!(Radix::Octal.to_string(), "Octal");
assert_eq!(Radix::Binary.to_string(), "Binary");
assert_eq!(format!("{:?}", Radix::Hexadecimal), "Radix::Hexadecimal");
assert_eq!(format!("{:?}", Radix::Decimal), "Radix::Decimal");
assert_eq!(format!("{:?}", Radix::Octal), "Radix::Octal");
assert_eq!(format!("{:?}", Radix::Binary), "Radix::Binary");
let hex = Radix::Hexadecimal.digit_test();
let dec = Radix::Decimal.digit_test();
let oct = Radix::Octal.digit_test();
let bin = Radix::Binary.digit_test();
assert!(!hex('/'));
assert!(hex('0'));
assert!(hex('9'));
assert!(!hex(':'));
assert!(!hex('?'));
assert!(hex('A'));
assert!(hex('F'));
assert!(!hex('G'));
assert!(!hex('_'));
assert!(hex('a'));
assert!(hex('f'));
assert!(!hex('g'));
assert!(!dec('/'));
assert!(dec('0'));
assert!(dec('9'));
assert!(!dec(':'));
assert!(!dec('?'));
assert!(!dec('A'));
assert!(!dec('F'));
assert!(!dec('G'));
assert!(!dec('_'));
assert!(!dec('a'));
assert!(!dec('f'));
assert!(!dec('g'));
assert!(!oct('/'));
assert!(oct('0'));
assert!(oct('7'));
assert!(!oct('8'));
assert!(!oct('9'));
assert!(!oct(':'));
assert!(!oct('?'));
assert!(!oct('A'));
assert!(!oct('F'));
assert!(!oct('G'));
assert!(!oct('_'));
assert!(!oct('a'));
assert!(!oct('f'));
assert!(!oct('g'));
assert!(!bin('/'));
assert!(bin('0'));
assert!(bin('1'));
assert!(!bin('2'));
assert!(!bin('9'));
assert!(!bin(':'));
assert!(!bin('?'));
assert!(!bin('A'));
assert!(!bin('F'));
assert!(!bin('G'));
assert!(!bin('_'));
assert!(!bin('a'));
assert!(!bin('f'));
assert!(!bin('g'));
}
#[test]
fn test_new() {
let _ = NumberParser::new();
let _ = NumberParser::default();
}
#[test]
fn test_parse_f64() {
let numpar = NumberParser::new();
let is = |vals: &str, valn: f64| {
let mut parser = parse_from_string(vals);
assert_eq!(numpar.parse_f64(parser.borrow_core()).unwrap(), valn);
};
let _err = |vals: &str| {
let mut parser = parse_from_string(vals);
assert!(numpar.parse_f64(parser.borrow_core()).is_err());
};
is("2.2204460492503131E-16", f64::EPSILON);
is("-1.7976931348623157E+308", f64::MIN);
is("2.2250738585072014E-308", f64::MIN_POSITIVE);
is("1.7976931348623157E+308", f64::MAX);
}