Skip to content

Commit

Permalink
Dummy commit, revert later.
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexhuszagh committed Jan 22, 2025
1 parent 0eddcdb commit 155a3d6
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 27 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `required_base_prefix` and `required_base_suffix` for our number formats, requiring base prefixes and/or suffixes when parsing, and allowing writing base prefixes and/or suffixes (#215).
- Added `NumberFormatBuilder::none()` for create a format with no flags set (#215).
- Added in many more digit separator flags for the `NumberFormat`, including for signs, base prefixes, base suffixes, and restricting digit separators at the start of the number (#215).
- Added many more pre-defined formatting constants (#215).

### Changed

Expand Down
5 changes: 3 additions & 2 deletions lexical-parse-integer/tests/algorithm_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod util;

use lexical_parse_integer::algorithm;
use lexical_parse_integer::options::SMALL_NUMBERS;
use lexical_util::error::Error;
use lexical_util::format::STANDARD;
use lexical_util::iterator::AsBytes;
#[cfg(feature = "power-of-two")]
Expand Down Expand Up @@ -135,7 +136,7 @@ fn algorithm_test() {

assert_eq!(parse_u32(b"12345"), Ok((12345, 5)));
assert_eq!(parse_u32(b"+12345"), Ok((12345, 6)));
assert_eq!(parse_u32(b"-12345"), Ok((0, 0)));
assert_eq!(parse_u32(b"-12345"), Err(Error::Empty(0)));
assert_eq!(parse_i32(b"12345"), Ok((12345, 5)));
assert_eq!(parse_i32(b"-12345"), Ok((-12345, 6)));
assert_eq!(parse_i32(b"+12345"), Ok((12345, 6)));
Expand Down Expand Up @@ -170,7 +171,7 @@ fn algorithm_128_test() {

assert_eq!(parse_u128(b"12345"), Ok((12345, 5)));
assert_eq!(parse_u128(b"+12345"), Ok((12345, 6)));
assert_eq!(parse_u128(b"-12345"), Ok((0, 0)));
assert_eq!(parse_u128(b"-12345"), Err(Error::Empty(0)));
assert_eq!(parse_i128(b"12345"), Ok((12345, 5)));
assert_eq!(parse_i128(b"-12345"), Ok((-12345, 6)));
assert_eq!(parse_i128(b"+12345"), Ok((12345, 6)));
Expand Down
197 changes: 186 additions & 11 deletions lexical-parse-integer/tests/api_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,16 @@ fn i32_integer_consecutive_digit_separator_test() {
.integer_consecutive_digit_separator(true)
.build_strict();

assert!(i32::from_lexical_with_options::<FORMAT>(b"3_1", &OPTIONS).is_ok());
assert!(i32::from_lexical_with_options::<FORMAT>(b"3__1", &OPTIONS).is_ok());
assert!(i32::from_lexical_with_options::<FORMAT>(b"_31", &OPTIONS).is_err());
assert!(i32::from_lexical_with_options::<FORMAT>(b"31_", &OPTIONS).is_err());
assert_eq!(i32::from_lexical_with_options::<FORMAT>(b"3_1", &OPTIONS), Ok(31));
assert_eq!(i32::from_lexical_with_options::<FORMAT>(b"3__1", &OPTIONS), Ok(31));
assert_eq!(
i32::from_lexical_with_options::<FORMAT>(b"_31", &OPTIONS),
Err(Error::InvalidDigit(0))
);
assert_eq!(
i32::from_lexical_with_options::<FORMAT>(b"31_", &OPTIONS),
Err(Error::InvalidDigit(2))
);
}

#[test]
Expand Down Expand Up @@ -349,13 +355,16 @@ fn base_prefix_and_suffix_test() {
.base_suffix(num::NonZeroU8::new(b'h'))
.build_strict();
const OPTIONS: Options = Options::new();
assert!(i32::from_lexical_with_options::<FORMAT>(b"+3h", &OPTIONS).is_ok());
assert!(i32::from_lexical_with_options::<FORMAT>(b"+0x3", &OPTIONS).is_ok());
assert!(i32::from_lexical_with_options::<FORMAT>(b"+0x3h", &OPTIONS).is_ok());
assert!(i32::from_lexical_with_options::<FORMAT>(b"+0x3h ", &OPTIONS).is_err());
assert!(i32::from_lexical_with_options::<FORMAT>(b"+0xh", &OPTIONS).is_err());
assert!(i32::from_lexical_with_options::<FORMAT>(b"+h", &OPTIONS).is_err());
assert!(i32::from_lexical_with_options::<FORMAT>(b"+0x", &OPTIONS).is_err());
assert_eq!(i32::from_lexical_with_options::<FORMAT>(b"+3h", &OPTIONS), Ok(3));
assert_eq!(i32::from_lexical_with_options::<FORMAT>(b"+0x3", &OPTIONS), Ok(3));
assert_eq!(i32::from_lexical_with_options::<FORMAT>(b"+0x3h", &OPTIONS), Ok(3));
assert_eq!(
i32::from_lexical_with_options::<FORMAT>(b"+0x3h ", &OPTIONS),
Err(Error::InvalidDigit(4))
);
assert_eq!(i32::from_lexical_with_options::<FORMAT>(b"+0xh", &OPTIONS), Err(Error::Empty(4)));
assert_eq!(i32::from_lexical_with_options::<FORMAT>(b"+h", &OPTIONS), Err(Error::Empty(2)));
assert_eq!(i32::from_lexical_with_options::<FORMAT>(b"+0x", &OPTIONS), Err(Error::Empty(3)));
}

#[test]
Expand Down Expand Up @@ -415,6 +424,8 @@ fn require_base_prefix_test() {

let value = i64::from_lexical_with_options::<PREFIX>(b"0d12345", &OPTIONS);
assert_eq!(value, Ok(12345));
let value = i64::from_lexical_with_options::<PREFIX>(b"0D12345", &OPTIONS);
assert_eq!(value, Ok(12345));
let value = i64::from_lexical_with_options::<PREFIX>(b"12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(0)));

Expand Down Expand Up @@ -447,3 +458,167 @@ fn require_base_prefix_test() {
let value = u64::from_lexical_with_options::<SUFFIX>(b"0d12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBaseSuffix(7)));
}

#[test]
#[cfg(all(feature = "format", feature = "power-of-two"))]
fn base_prefix_digit_separator_edge_cases_test() {
// TODO: Add in these tests to parse_float
use core::num;

const OPTIONS: Options = Options::new();
const NO_PREFIX: u128 = NumberFormatBuilder::new()
.digit_separator(num::NonZeroU8::new(b'_'))
.leading_digit_separator(true)
.build_strict();

let value = i64::from_lexical_with_options::<NO_PREFIX>(b"_+12345", &OPTIONS);
assert_eq!(value, Err(Error::InvalidDigit(1)));

let value = i64::from_lexical_with_options::<NO_PREFIX>(b"+_12345", &OPTIONS);
assert_eq!(value, Ok(12345));

let value = i64::from_lexical_with_options::<NO_PREFIX>(b"1", &OPTIONS);
assert_eq!(value, Ok(1));

const OPT_PREFIX: u128 = NumberFormatBuilder::new()
.digit_separator(num::NonZeroU8::new(b'_'))
.base_prefix(num::NonZeroU8::new(b'd'))
.leading_digit_separator(true)
.build_strict();

let value = i64::from_lexical_with_options::<OPT_PREFIX>(b"1", &OPTIONS);
assert_eq!(value, Ok(1));

const PREFIX: u128 =
NumberFormatBuilder::rebuild(OPT_PREFIX).required_base_prefix(true).build_strict();

let value = i64::from_lexical_with_options::<PREFIX>(b"_+0d12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(0)));

let value = i64::from_lexical_with_options::<PREFIX>(b"+_0d12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(1)));

let value = i64::from_lexical_with_options::<PREFIX>(b"+0d12345", &OPTIONS);
assert_eq!(value, Ok(12345));

let value = i64::from_lexical_with_options::<PREFIX>(b"+0d_12345", &OPTIONS);
assert_eq!(value, Ok(12345));

const LEAD_PREFIX: u128 = NumberFormatBuilder::rebuild(PREFIX)
.base_prefix_leading_digit_separator(true)
.build_strict();

let value = i64::from_lexical_with_options::<LEAD_PREFIX>(b"_+0d12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(0)));

let value = i64::from_lexical_with_options::<LEAD_PREFIX>(b"+_0d12345", &OPTIONS);
assert_eq!(value, Ok(12345));

let value = i64::from_lexical_with_options::<LEAD_PREFIX>(b"+_0d_12345", &OPTIONS);
assert_eq!(value, Ok(12345));

let value = i64::from_lexical_with_options::<LEAD_PREFIX>(b"+0_d12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(1)));

let value = i64::from_lexical_with_options::<LEAD_PREFIX>(b"+_0d__12345", &OPTIONS);
assert_eq!(value, Err(Error::InvalidDigit(4)));

const INTERN_PREFIX: u128 = NumberFormatBuilder::rebuild(PREFIX)
.base_prefix_internal_digit_separator(true)
.build_strict();

let value = i64::from_lexical_with_options::<INTERN_PREFIX>(b"_+0d12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(0)));

let value = i64::from_lexical_with_options::<INTERN_PREFIX>(b"+_0d12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(1)));

let value = i64::from_lexical_with_options::<INTERN_PREFIX>(b"+_0d_12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(1)));

let value = i64::from_lexical_with_options::<INTERN_PREFIX>(b"+0_d12345", &OPTIONS);
assert_eq!(value, Ok(12345));

let value = i64::from_lexical_with_options::<INTERN_PREFIX>(b"+0d__12345", &OPTIONS);
assert_eq!(value, Err(Error::InvalidDigit(3)));

const TRAIL_PREFIX: u128 = NumberFormatBuilder::rebuild(PREFIX)
.base_prefix_trailing_digit_separator(true)
.leading_digit_separator(false)
.build_strict();

let value = i64::from_lexical_with_options::<TRAIL_PREFIX>(b"_+0d12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(0)));

let value = i64::from_lexical_with_options::<TRAIL_PREFIX>(b"+_0d12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(1)));

let value = i64::from_lexical_with_options::<TRAIL_PREFIX>(b"+_0d_12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(1)));

let value = i64::from_lexical_with_options::<TRAIL_PREFIX>(b"+0_d12345", &OPTIONS);
assert_eq!(value, Err(Error::MissingBasePrefix(1)));

let value = i64::from_lexical_with_options::<TRAIL_PREFIX>(b"+0d_12345", &OPTIONS);
assert_eq!(value, Ok(12345));

let value = i64::from_lexical_with_options::<TRAIL_PREFIX>(b"+0d__12345", &OPTIONS);
assert_eq!(value, Err(Error::InvalidDigit(4)));

// TODO: Need all the custom suffix ones too

// const SUFFIX: u128 = NumberFormatBuilder::rebuild(PREFIX)
// .base_suffix(num::NonZeroU8::new(b'z'))
// .required_base_suffix(true)
// .build_strict();
// let value = i64::from_lexical_with_options::<SUFFIX>(b"0d12345z",
// &OPTIONS); assert_eq!(value, Ok(12345));
// let value = i64::from_lexical_with_options::<SUFFIX>(b"0d12345",
// &OPTIONS); assert_eq!(value, Err(Error::MissingBaseSuffix(7)));
//
// let value = i64::from_lexical_with_options::<SUFFIX>(b"-0d12345z",
// &OPTIONS); assert_eq!(value, Ok(-12345));
// let value = i64::from_lexical_with_options::<SUFFIX>(b"-0d12345",
// &OPTIONS); assert_eq!(value, Err(Error::MissingBaseSuffix(8)));
//
// let value = u64::from_lexical_with_options::<SUFFIX>(b"0d12345z",
// &OPTIONS); assert_eq!(value, Ok(12345));
// let value = u64::from_lexical_with_options::<SUFFIX>(b"0d12345",
// &OPTIONS); assert_eq!(value, Err(Error::MissingBaseSuffix(7)));

// TODO: This fails: I think this is the correct behavior actually...
// TODO: This is wrong, we should fix this
// TODO: Should migrate `parse_base_prefix` and `parse_base_suffix` to
// the end...
// TODO: base_prefix_leading_digit_separator
// TODO: base_prefix_internal_digit_separator
// TODO: base_prefix_trailing_digit_separator (identical to
// `integer_leading_digit_separator`)
// TODO: base_prefix_consecutive_digit_separator
// TODO: leading_base_suffix_digit_separator (identical to
// `trailing_digit_separator`, depending on context)
// TODO: internal_base_suffix_digit_separator
// TODO: trailing_base_suffix_digit_separator
// TODO: consecutive_base_suffix_digit_separator
// TODO: start_digit_separator (absolute start, can overlap with
// leading_base_prefix_digit_separator or leading_integer_digit_separator
// depending on context)
// let value = i64::from_lexical_with_options::<PREFIX>(b"+0d_12345",
// &OPTIONS); assert_eq!(value, Err(Error::InvalidDigit(3)));
//
// // TODO:> Add suffix
//
// // TODO: Need Post-base suffix digit separator
// // This shouldn't be internal I don't think...
//
// const INTERNAL: u128 = NumberFormatBuilder::new()
// .digit_separator(num::NonZeroU8::new(b'_'))
// .base_prefix(num::NonZeroU8::new(b'd'))
// .required_base_prefix(true)
// .internal_digit_separator(true)
// .build_strict();
// let value = i64::from_lexical_with_options::<INTERNAL>(b"+0d_12345",
// &OPTIONS); assert_eq!(value, Err(Error::InvalidDigit(3)));

// TODO: Need
}
18 changes: 17 additions & 1 deletion lexical-util/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@
//! # Pre-Defined Formats
//!
//! These are the pre-defined formats for parsing numbers from various
//! programming, markup, and data languages.
//! programming, markup, and data languages. This does not contain those
//! created via a custom formatting API in the language, such as [`UpperHex`].
//!
//! [`UpperHex`]: core::fmt::UpperHex
//!
//! - [`STANDARD`]: Standard number format. This is identical to the Rust string
//! format.
Expand All @@ -55,6 +58,19 @@
doc = "
- [`RUST_LITERAL`]: Number format for a [`Rust`] literal floating-point number.
- [`RUST_STRING`]: Number format to parse a [`Rust`] float from string.
"
)]
#![cfg_attr(
all(feature = "format", feature = "power-of-two"),
doc = "
- [`RUST_HEX_LITERAL`]: Number format for a [`Rust`] literal hexadecimal number.
- [`RUST_BINARY_LITERAL`]: Number format for a [`Rust`] literal binary number.
- [`RUST_OCTAL_LITERAL`]: Number format for a [`Rust`] literal octal number.
"
)]
#![cfg_attr(
feature = "format",
doc = "
- [`PYTHON_LITERAL`]: Number format for a [`Python`] literal floating-point number.
- [`PYTHON_STRING`]: Number format to parse a [`Python`] float from string.
- [`PYTHON3_LITERAL`]: Number format for a [`Python3`] literal floating-point number.
Expand Down
Loading

0 comments on commit 155a3d6

Please sign in to comment.