Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add patches for feature configurations and serializing radices. #162

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Have consistent errors when an invalid leading digit is found for floating point numbers to always be `Error::InvalidDigit`.
- Incorrect parsing of consecutive digit separators.
- Inaccuracies when parsing digit separators at various positions leading to incorect errors being returned.
- Selecting only a subset of parse and/or write features would cause compilation errors.
- Fixed bug with writing integers with custom radices.

## [1.0.1] 2024-09-16

Expand Down
34 changes: 34 additions & 0 deletions ci/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ FEATURES=(
"format,radix"
)

check_error() {
local feature=$1
if 2>/dev/null cargo check --no-default-features --features="${feature}" ; then
>&2 echo "The feature ${feature} did not error..."
exit 1
fi
}

# Don't build the target, but ensure the syntax is correct.
check() {
if [ ! -z $NO_FEATURES ]; then
Expand All @@ -56,6 +64,18 @@ check() {
cd ../lexical-write-integer
cargo check --tests

# ensure our partial features aren't allowed, as are unsupported features
cd ../lexical-core
partial=(parse write floats integers)
for feature in "${partial[@]}"; do
check_error "${feature}"
done

cd ../lexical
for feature in "${partial[@]}"; do
check_error "${feature}"
done

cd ..
}

Expand All @@ -82,6 +102,20 @@ test() {
cargo test --features=radix,format,compact $DOCTESTS --release
# NOTE: This tests a regressions, related to #96.
cargo test --features=format $DOCTESTS

# this fixes an issue where the lexical and lexical-core tests weren't being run
cd lexical-core
cargo test $test_features,format
cargo test $test_features,radix
cargo test $test_features,format,radix
cd ..

# this fixes an issue where the lexical and lexical-core tests weren't being run
cd lexical
cargo test $test_features,format
cargo test $test_features,radix
cargo test $test_features,format,radix
cd ..
}

# Dry-run bench target
Expand Down
23 changes: 16 additions & 7 deletions lexical-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ f16 = [
"lexical-write-float?/f16"
]

# Internal only features.
# INTERNAL ONLY
# -------------
# Internal only features. These are not meant to be used directly.
# Enable the lint checks.
lint = [
"lexical-util/lint",
Expand All @@ -117,16 +119,23 @@ lint = [
"lexical-parse-float?/lint"
]
# Add support for writing numbers.
write = []
# Library users should use `write-integers` and `write-floats` instead.
write = ["lexical-util/write"]
# Add support for parsing numbers.
parse = []
# Library users should use `parse-integers` and `parse-floats` instead.
parse = ["lexical-util/parse"]
# Add support for conversions to or from integers.
integers = []
# Library users should use `write-integers` and `parse-integers` instead.
integers = ["lexical-util/integers"]
# Add support for conversions to or from floats.
floats = []
# Library users should use `write-floats` and `parse-floats` instead.
floats = ["lexical-util/floats"]

# Currently unsupported.
# Enable support for 128-bit floats.
# UNSUPPORTED
# -----------
# Currently unsupported features.
# Enable support for 128-bit floats. Unsupported and unlikely to ever be.
# https://github.com/Alexhuszagh/rust-lexical/issues/46
f128 = [
"lexical-util/f128",
"lexical-parse-float?/f128",
Expand Down
120 changes: 120 additions & 0 deletions lexical-core/tests/float_pow2_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#![cfg(feature = "power-of-two")]
#![cfg(feature = "parse-floats")]
#![cfg(feature = "write-floats")]

use approx::assert_relative_eq;

const F32_DATA: [f32; 31] = [
0.,
0.1,
1.,
1.1,
12.,
12.1,
123.,
123.1,
1234.,
1234.1,
12345.,
12345.1,
123456.,
123456.1,
1234567.,
1234567.1,
12345678.,
12345678.1,
123456789.,
123456789.1,
123456789.12,
123456789.123,
123456789.1234,
123456789.12345,
1.2345678912345e8,
1.2345e+8,
1.2345e+11,
1.2345e+38,
1.2345e-8,
1.2345e-11,
1.2345e-38,
];
const F64_DATA: [f64; 33] = [
0.,
0.1,
1.,
1.1,
12.,
12.1,
123.,
123.1,
1234.,
1234.1,
12345.,
12345.1,
123456.,
123456.1,
1234567.,
1234567.1,
12345678.,
12345678.1,
123456789.,
123456789.1,
123456789.12,
123456789.123,
123456789.1234,
123456789.12345,
1.2345678912345e8,
1.2345e+8,
1.2345e+11,
1.2345e+38,
1.2345e+308,
1.2345e-8,
1.2345e-11,
1.2345e-38,
1.2345e-299,
];

macro_rules! test_radix {
($f:ident, $radix:expr, $buffer:ident, $data:ident) => {{
use lexical_core::{
FromLexicalWithOptions,
NumberFormatBuilder,
ParseFloatOptions,
ToLexicalWithOptions,
WriteFloatOptions,
};

const FORMAT: u128 = NumberFormatBuilder::from_radix($radix);
println!("Testing radix {} for type {}...", $radix, stringify!($f));

let write_options = WriteFloatOptions::builder().exponent(b'^').build().unwrap();
let parse_options = ParseFloatOptions::builder().exponent(b'^').build().unwrap();
for &float in $data.iter() {
let data = float.to_lexical_with_options::<FORMAT>(&mut $buffer, &write_options);
let roundtrip = $f::from_lexical_with_options::<FORMAT>(data, &parse_options).unwrap();
assert_relative_eq!(float, roundtrip, epsilon = 1e-6, max_relative = 3e-6);
}
}};
}

macro_rules! test_all {
($f:ident, $buffer:ident, $data:ident) => {{
test_radix!($f, 2, $buffer, $data);
test_radix!($f, 4, $buffer, $data);
test_radix!($f, 8, $buffer, $data);
test_radix!($f, 16, $buffer, $data);
test_radix!($f, 32, $buffer, $data);
test_radix!($f, 36, $buffer, $data);
}};
}

#[test]
fn parse_f32_pow2_roundtrip_test() {
let mut buffer = [0u8; 1024];
test_all!(f32, buffer, F32_DATA);
}

#[test]
fn parse_f64_pow2_roundtrip_test() {
let mut buffer = [0u8; 1024];
test_all!(f64, buffer, F64_DATA);
}
1 change: 1 addition & 0 deletions lexical-core/tests/float_radix_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ macro_rules! test_radix {
};

const FORMAT: u128 = NumberFormatBuilder::from_radix($radix);
println!("Testing radix {} for type {}...", $radix, stringify!($f));

let write_options = WriteFloatOptions::builder().exponent(b'^').build().unwrap();
let parse_options = ParseFloatOptions::builder().exponent(b'^').build().unwrap();
Expand Down
11 changes: 8 additions & 3 deletions lexical-parse-float/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,20 @@ compact = [
# Enable support for 16-bit floats.
f16 = ["lexical-util/f16"]

# Internal only features.
# INTERNAL ONLY
# -------------
# Internal only features. These are not meant to be used directly.
# Enable the lint checks.
lint = [
"lexical-util/lint",
"lexical-parse-integer/lint"
]

# Currently unsupported.
# Enable support for 128-bit floats.
# UNSUPPORTED
# -----------
# Currently unsupported features.
# Enable support for 128-bit floats. Unsupported and unlikely to ever be.
# https://github.com/Alexhuszagh/rust-lexical/issues/46
f128 = ["lexical-util/f128"]

[package.metadata.docs.rs]
Expand Down
4 changes: 3 additions & 1 deletion lexical-parse-integer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ format = ["lexical-util/format"]
# Reduce code size at the cost of performance.
compact = ["lexical-util/compact"]

# Internal only features.
# INTERNAL ONLY
# -------------
# Internal only features. These are not meant to be used directly.
# Enable the lint checks.
lint = ["lexical-util/lint"]

Expand Down
11 changes: 8 additions & 3 deletions lexical-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ parse-integers = ["parse", "integers"]
parse-floats = ["parse", "floats"]
# Reduce code size at the cost of performance.
compact = []
# Add support for the `f16` and `b16` half-point floating point numbers.
f16 = ["parse-floats", "write-floats"]

# Internal only features.
# Enable the lint checks.
Expand All @@ -68,11 +70,14 @@ integers = []
# Add support for conversions to or from floats.
floats = []

# Currently unsupported.
# UNSUPPORTED
# -----------
# Currently unsupported features.
# Enable support for 128-bit floats. Unsupported and unlikely to ever be.
# https://github.com/Alexhuszagh/rust-lexical/issues/46
# Enable support for 16-bit floats.
f16 = ["floats"]
# Enable support for 128-bit floats.
f128 = ["floats"]
f128 = ["parse-floats", "write-floats"]

[package.metadata.docs.rs]
features = ["radix", "format", "write-integers", "write-floats", "parse-integers", "parse-floats"]
20 changes: 20 additions & 0 deletions lexical-util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,26 @@
clippy::semicolon_inside_block,
)]

// Ensure our features are properly enabled. This means no parse without
// parse support, etc.
#[cfg(all(feature = "parse", not(any(feature = "parse-integers", feature = "parse-floats"))))]
compile_error!(
"Do not use the `parse` feature directly. Use `parse-integers` and/or `parse-floats` instead."
);

#[cfg(all(feature = "write", not(any(feature = "write-integers", feature = "write-floats"))))]
compile_error!(
"Do not use the `write` feature directly. Use `write-integers` and/or `write-floats` instead."
);

#[cfg(all(feature = "integers", not(any(feature = "write-integers", feature = "parse-integers"))))]
compile_error!("Do not use the `integers` feature directly. Use `write-integers` and/or `parse-integers` instead.");

#[cfg(all(feature = "floats", not(any(feature = "write-floats", feature = "parse-floats"))))]
compile_error!(
"Do not use the `floats` feature directly. Use `write-floats` and/or `parse-floats` instead."
);

pub mod algorithm;
pub mod ascii;
pub mod assert;
Expand Down
11 changes: 8 additions & 3 deletions lexical-write-float/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,20 @@ compact = [
# Enable support for 16-bit floats.
f16 = ["lexical-util/f16"]

# Internal only features.
# INTERNAL ONLY
# -------------
# Internal only features. These are not meant to be used directly.
# Enable the lint checks.
lint = [
"lexical-util/lint",
"lexical-write-integer/lint"
]

# Currently unsupported.
# Enable support for 128-bit floats.
# UNSUPPORTED
# -----------
# Currently unsupported features.
# Enable support for 128-bit floats. Unsupported and unlikely to ever be.
# https://github.com/Alexhuszagh/rust-lexical/issues/46
f128 = ["lexical-util/f128"]

[package.metadata.docs.rs]
Expand Down
4 changes: 3 additions & 1 deletion lexical-write-integer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ format = ["lexical-util/format"]
# Reduce code size at the cost of performance.
compact = ["lexical-util/compact"]

# Internal only features.
# INTERNAL ONLY
# -------------
# Internal only features. These are not meant to be used directly.
# Enable the lint checks.
lint = ["lexical-util/lint"]

Expand Down
Loading