浏览代码

Merge #214

214: Ignore case for float parsing of text special values r=cuviper a=tspiteri

This copies some of the standard library fixes of <https://github.com/rust-lang/rust/pull/78618>.

Co-authored-by: Trevor Spiteri <tspiteri@ieee.org>
bors[bot] 3 年之前
父节点
当前提交
ee28ebb3f6
共有 1 个文件被更改,包括 42 次插入6 次删除
  1. 42 6
      src/lib.rs

+ 42 - 6
src/lib.rs

@@ -210,6 +210,14 @@ impl fmt::Display for ParseFloatError {
     }
 }
 
+fn str_to_ascii_lower_eq_str(a: &str, b: &str) -> bool {
+    a.len() == b.len()
+        && a.bytes().zip(b.bytes()).all(|(a, b)| {
+            let a_to_ascii_lower = a | (((b'A' <= a && a <= b'Z') as u8) << 5);
+            a_to_ascii_lower == b
+        })
+}
+
 // FIXME: The standard library from_str_radix on floats was deprecated, so we're stuck
 // with this implementation ourselves until we want to make a breaking change.
 // (would have to drop it from `Num` though)
@@ -232,12 +240,18 @@ macro_rules! float_trait_impl {
                 }
 
                 // Special values
-                match src {
-                    "inf"   => return Ok(core::$t::INFINITY),
-                    "-inf"  => return Ok(core::$t::NEG_INFINITY),
-                    "NaN"   => return Ok(core::$t::NAN),
-                    "-NaN"  => return Ok(-core::$t::NAN),
-                    _       => {},
+                if str_to_ascii_lower_eq_str(src, "inf")
+                    || str_to_ascii_lower_eq_str(src, "infinity")
+                {
+                    return Ok(core::$t::INFINITY);
+                } else if str_to_ascii_lower_eq_str(src, "-inf")
+                    || str_to_ascii_lower_eq_str(src, "-infinity")
+                {
+                    return Ok(core::$t::NEG_INFINITY);
+                } else if str_to_ascii_lower_eq_str(src, "nan") {
+                    return Ok(core::$t::NAN);
+                } else if str_to_ascii_lower_eq_str(src, "-nan") {
+                    return Ok(-core::$t::NAN);
                 }
 
                 fn slice_shift_char(src: &str) -> Option<(char, &str)> {
@@ -516,6 +530,28 @@ fn from_str_radix_multi_byte_fail() {
     assert!(f32::from_str_radix("0.2E™1", 10).is_err());
 }
 
+#[test]
+fn from_str_radix_ignore_case() {
+    assert_eq!(
+        f32::from_str_radix("InF", 16).unwrap(),
+        ::core::f32::INFINITY
+    );
+    assert_eq!(
+        f32::from_str_radix("InfinitY", 16).unwrap(),
+        ::core::f32::INFINITY
+    );
+    assert_eq!(
+        f32::from_str_radix("-InF", 8).unwrap(),
+        ::core::f32::NEG_INFINITY
+    );
+    assert_eq!(
+        f32::from_str_radix("-InfinitY", 8).unwrap(),
+        ::core::f32::NEG_INFINITY
+    );
+    assert!(f32::from_str_radix("nAn", 4).unwrap().is_nan());
+    assert!(f32::from_str_radix("-nAn", 4).unwrap().is_nan());
+}
+
 #[test]
 fn wrapping_is_num() {
     fn require_num<T: Num>(_: &T) {}