Skip to content

Commit

Permalink
Merge pull request #162 from Alexhuszagh/feature_check
Browse files Browse the repository at this point in the history
Add patches for feature configurations and serializing radices.
  • Loading branch information
Alexhuszagh committed Sep 25, 2024
2 parents f6d943c + dfad54f commit 145efa5
Show file tree
Hide file tree
Showing 16 changed files with 288 additions and 51 deletions.
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

0 comments on commit 145efa5

Please sign in to comment.