Skip to content

Commit ef65884

Browse files
KSXGitHubclaude
andauthored
fix!: rejects NaN in Fraction (#428)
NaN passed both the upper-bound and lower-bound comparisons because every ordered comparison against NaN is false, so an invalid value reached the constructor. Add an explicit is_nan check and a NotANumber variant so the value is rejected at the boundary instead of relying on downstream consumers to special-case NaN. https://claude.ai/code/session_01SEknK8pBtZzArSLx7wvrLj Co-authored-by: Claude <noreply@anthropic.com>
1 parent 4b0f192 commit ef65884

2 files changed

Lines changed: 18 additions & 0 deletions

File tree

src/args/fraction.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@ pub enum ConversionError {
1818
/// Provided value is less than 0.
1919
#[display("less than 0")]
2020
LowerBound,
21+
/// Provided value is `NaN`.
22+
#[display("not a number")]
23+
NotANumber,
2124
}
2225

2326
impl Fraction {
2427
/// Create a [`Fraction`].
2528
pub fn new(value: f32) -> Result<Self, ConversionError> {
2629
use ConversionError::*;
30+
if value.is_nan() {
31+
return Err(NotANumber);
32+
}
2733
if value >= 1.0 {
2834
return Err(UpperBound);
2935
}

tests/args_fraction.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ fn equal_to_one() {
4848
);
4949
}
5050

51+
#[test]
52+
fn not_a_number() {
53+
let actual_error = "NaN".parse::<Fraction>().expect_err("cause nan error");
54+
let actual_message = actual_error.to_string();
55+
let expected_error = Conversion(NotANumber);
56+
let expected_message = "not a number".to_string();
57+
assert_eq!(
58+
(actual_error, actual_message),
59+
(expected_error, expected_message),
60+
);
61+
}
62+
5163
#[test]
5264
fn invalid_float_literal() {
5365
let actual = "a"

0 commit comments

Comments
 (0)