use std::convert::TryFrom;
use uninum::{Number, ParseNumberError, TryFromNumberError, num};
#[test]
fn test_parsing_errors_comprehensive() {
assert!(matches!(Number::try_from(""), Err(ParseNumberError::Empty)));
assert!(matches!(
Number::try_from(" "),
Err(ParseNumberError::Empty)
));
assert!(matches!(
Number::try_from("\t\n"),
Err(ParseNumberError::Empty)
));
assert!(matches!(
Number::try_from("abc"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("12abc"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("abc12"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("12a34"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("12.34.56"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("1.2.3.4"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from(".."),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42u9"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42u1024"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42i7"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42f16"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42f128"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42U8"),
Err(ParseNumberError::InvalidFormat(_))
)); assert!(matches!(
Number::try_from("42F64"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0xGG"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0xZZ"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0b102"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0b2"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0o9"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0o80"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("4294967296u32"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("18446744073709551616u64"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("2147483648i32"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("-2147483649i32"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("9223372036854775808i64"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("-9223372036854775809i64"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(Number::try_from("nanf64").is_err());
assert!(matches!(
Number::try_from("-"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("+"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("."),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("e10"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("1e"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0x"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0b"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0o"),
Err(ParseNumberError::InvalidFormat(_))
));
}
#[test]
fn test_error_messages() {
let empty_err = Number::try_from("").unwrap_err();
assert_eq!(empty_err.to_string(), "Cannot parse empty string as number");
let invalid_err = Number::try_from("abc123").unwrap_err();
assert!(invalid_err.to_string().contains("Invalid number format"));
assert!(invalid_err.to_string().contains("abc123"));
let _: &dyn std::error::Error = &empty_err;
let _: &dyn std::error::Error = &invalid_err;
}
#[test]
fn test_unicode_and_special_chars() {
assert!(matches!(
Number::try_from("−42"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("+42"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42🔢"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("🔢42"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(Number::try_from("42\u{00A0}").is_err());
assert!(matches!(
Number::try_from("4\u{200B}2"),
Err(ParseNumberError::InvalidFormat(_))
)); }
#[test]
fn test_malformed_scientific_notation() {
assert!(matches!(
Number::try_from("1e"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("1E"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("e10"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("E10"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("1e2e3"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("1E2E3"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("1e++2"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("1e--2"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("1e+-2"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("1e2.5"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("1e2u32"),
Err(ParseNumberError::InvalidFormat(_))
));
}
#[test]
fn test_base_prefix_case_insensitive() {
assert!(Number::try_from("0X1a").is_ok()); assert!(Number::try_from("0O755").is_ok()); assert!(Number::try_from("0B101").is_ok());
assert!(matches!(
Number::try_from("0xhello"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0o999"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0b222"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0x"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0o"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0b"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0x1.a"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0o7.5"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("0b1.0"),
Err(ParseNumberError::InvalidFormat(_))
));
}
#[test]
fn test_underscore_validation() {
assert!(Number::try_from("_42").is_err()); assert!(Number::try_from("42_").is_err()); assert!(Number::try_from("4__2").is_err()); assert!(Number::try_from("42_.5").is_err()); assert!(Number::try_from("42._5").is_err()); assert!(Number::try_from("1e1_0").is_err());
assert!(Number::try_from("1_000").is_ok()); assert!(Number::try_from("0xff_00").is_ok()); assert!(Number::try_from("0x1a_2b_3c").is_ok()); assert!(Number::try_from("1_234_567").is_ok()); assert_eq!(
Number::try_from("-0xFF_FF").unwrap(),
Number::from(-65_535i64)
);
}
#[test]
fn test_very_long_inputs() {
let long_invalid = "a".repeat(1000);
assert!(matches!(
Number::try_from(long_invalid.as_str()),
Err(ParseNumberError::InvalidFormat(_))
));
let long_number = "1".repeat(1000);
let result = Number::try_from(long_number.as_str());
if result.is_err() {
assert!(matches!(result, Err(ParseNumberError::InvalidFormat(_))));
}
assert!(matches!(
Number::try_from("42u8888888888888888888"),
Err(ParseNumberError::InvalidFormat(_))
));
}
#[test]
fn test_null_and_control_chars() {
assert!(matches!(
Number::try_from("42\0"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("\x22"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42\x01"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42\x1F"),
Err(ParseNumberError::InvalidFormat(_))
));
assert!(matches!(
Number::try_from("42\x7F"),
Err(ParseNumberError::InvalidFormat(_))
));
}
#[test]
fn test_conversion_functions_coverage() {
let empty_err = ParseNumberError::Empty;
assert_eq!(
format!("{empty_err}"),
"Cannot parse empty string as number"
);
let invalid_err = ParseNumberError::InvalidFormat("test".to_string());
assert_eq!(format!("{invalid_err}"), "Invalid number format: test");
let type_mismatch = TryFromNumberError::TypeMismatch {
from: "F64",
to: "u32",
};
assert_eq!(format!("{type_mismatch}"), "Cannot convert F64 to u32");
let range_err = TryFromNumberError::OutOfRange {
value: "256".to_string(),
target: "u8",
};
assert_eq!(format!("{range_err}"), "Value 256 is out of range for u8");
let precision_err = TryFromNumberError::TypeMismatch {
from: "F64",
to: "i32",
};
assert_eq!(format!("{precision_err}"), "Cannot convert F64 to i32");
}
#[test]
fn test_internal_parsing_coverage() {
let s = String::from("42");
assert_eq!(Number::try_from(s).unwrap(), Number::from(42u64));
assert_eq!(Number::try_from(" 42 ").unwrap(), Number::from(42u64));
assert_eq!(Number::try_from("\t42\t").unwrap(), Number::from(42u64));
assert_eq!(Number::try_from("\n42\n").unwrap(), Number::from(42u64));
assert_eq!(Number::try_from("\r42\r").unwrap(), Number::from(42u64));
assert!(Number::try_from("_42").is_err());
assert!(Number::try_from("42_").is_err());
assert!(Number::try_from("4__2").is_err());
assert!(Number::try_from("1e1_0").is_err());
assert_eq!(Number::try_from("1_000").unwrap(), Number::from(1000u64));
assert_eq!(Number::try_from("0x1_a").unwrap(), Number::from(26u64));
assert_eq!(
Number::try_from("0b1010_1010").unwrap(),
Number::from(170u64)
);
assert_eq!(Number::try_from("0xff").unwrap(), Number::from(255u64));
assert_eq!(Number::try_from("0xFF").unwrap(), Number::from(255u64));
assert_eq!(Number::try_from("0o77").unwrap(), Number::from(63u64));
assert_eq!(Number::try_from("0O77").unwrap(), Number::from(63u64));
assert_eq!(Number::try_from("0b101").unwrap(), Number::from(5u64));
assert_eq!(Number::try_from("0B101").unwrap(), Number::from(5u64));
assert_eq!(Number::try_from("+42").unwrap(), Number::from(42u64));
assert_eq!(Number::try_from("+0xff").unwrap(), Number::from(255u64));
assert_eq!(Number::try_from("-42").unwrap(), Number::from(-42i64));
assert_eq!(Number::try_from("-0x10").unwrap(), Number::from(-16i64));
assert_eq!(Number::try_from("255").unwrap(), Number::from(255u64));
assert_eq!(Number::try_from("256").unwrap(), Number::from(256u64));
assert_eq!(Number::try_from("65535").unwrap(), Number::from(65535u64));
assert_eq!(Number::try_from("65536").unwrap(), Number::from(65536u64));
assert_eq!(Number::try_from("-128").unwrap(), Number::from(-128i64));
assert_eq!(Number::try_from("-129").unwrap(), Number::from(-129i64));
assert_eq!(Number::try_from("-32768").unwrap(), Number::from(-32768i64));
assert_eq!(Number::try_from("-32769").unwrap(), Number::from(-32769i64));
assert!(Number::try_from("42u64").is_err());
assert!(Number::try_from("42i64").is_err());
assert!(Number::try_from("42u64").is_err());
assert!(Number::try_from("42i64").is_err());
assert!(Number::try_from("3.16f64").is_err());
#[cfg(feature = "decimal")]
{
assert!(
Number::try_from("3.16")
.unwrap()
.try_get_decimal()
.is_some()
);
assert!(
Number::try_from("1e-5")
.unwrap()
.try_get_decimal()
.is_some()
);
assert!(Number::try_from("1e50").unwrap().try_get_f64().is_some()); }
#[cfg(not(feature = "decimal"))]
{
assert!(Number::try_from("3.16").unwrap().try_get_f64().is_some());
assert!(Number::try_from("1e-5").unwrap().try_get_f64().is_some());
}
assert!(Number::try_from("inf").unwrap().is_infinite());
assert!(Number::try_from("nan").unwrap().is_nan());
assert!(Number::try_from("-inf").unwrap().is_infinite());
assert!(matches!(
Number::try_from("not_a_number"),
Err(ParseNumberError::InvalidFormat(_))
));
}
#[test]
fn test_tryfrom_error_paths() {
let nan_f64 = num!(f64::NAN);
let inf_f64 = num!(f64::INFINITY);
let neg_inf_f64 = num!(f64::NEG_INFINITY);
let neg_f64 = num!(-1.0);
assert!(matches!(
u32::try_from(nan_f64),
Err(TryFromNumberError::TypeMismatch { .. })
));
assert!(matches!(
u32::try_from(inf_f64),
Err(TryFromNumberError::OutOfRange { .. })
));
assert!(matches!(
u32::try_from(neg_inf_f64),
Err(TryFromNumberError::OutOfRange { .. })
));
assert!(matches!(
u32::try_from(neg_f64),
Err(TryFromNumberError::OutOfRange { .. })
));
let large_f64 = num!(u64::MAX as f64 * 2.0);
assert!(matches!(
u64::try_from(large_f64),
Err(TryFromNumberError::OutOfRange { .. })
));
let max_u64 = Number::from(u64::MAX);
assert!(matches!(
i64::try_from(max_u64),
Err(TryFromNumberError::OutOfRange { .. })
));
#[cfg(feature = "decimal")]
{
use rust_decimal::Decimal;
let frac_decimal = Number::from(Decimal::new(314, 2)); assert!(matches!(
u32::try_from(frac_decimal),
Err(TryFromNumberError::TypeMismatch { .. })
));
assert!(matches!(
Decimal::try_from(num!(f64::INFINITY)),
Err(TryFromNumberError::TypeMismatch { .. })
));
}
}