Repository: ron-rs/ron (rust)

Issue:
Underscores in numerals
This is a pretty straightforward feature request for `_` characters in numbers in ron, similar to how they are allowed in Rust. I'm really just looking to make my files with big numbers slightly more readable.

To clarify, I want to be able to write this:
```
foo: 123_456_789.0
```

Currently, ron gives a `Parser(ExpectedArrayEnd, Position { ... })` error at the underscore.

Pull request description:
Allow underscores in integers
Fixes #134 

Patch:
diff --git a/Cargo.toml b/Cargo.toml
index 5322fa05..ca00a109 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "ron"
-version = "0.4.0"
+version = "0.4.1"
 license = "MIT/Apache-2.0"
 keywords = ["parser", "serde", "serialization"]
 authors = [
diff --git a/docs/grammar.md b/docs/grammar.md
index fa65719f..0f40039d 100644
--- a/docs/grammar.md
+++ b/docs/grammar.md
@@ -46,7 +46,7 @@ value = unsigned | signed | float | string | char | bool | option | list | map |
 
 ```ebnf
 digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
-unsigned = ["0", ("x" | "b" | "o")], digit, { digit };
+unsigned = ["0", ("x" | "b" | "o")], digit, { digit | '_' };
 signed = ["+" | "-"], unsigned;
 float = float_std | float_frac;
 float_std = ["+" | "-"], digit, { digit }, ".", {digit}, [float_exp];
diff --git a/src/de/error.rs b/src/de/error.rs
index bbaeef03..5c6ed15d 100644
--- a/src/de/error.rs
+++ b/src/de/error.rs
@@ -52,6 +52,7 @@ pub enum ParseError {
     NoSuchExtension(String),
 
     UnclosedBlockComment,
+    UnderscoreAtBeginning,
     UnexpectedByte(char),
 
     Utf8Error(Utf8Error),
@@ -115,6 +116,7 @@ impl StdError for Error {
 
                 ParseError::Utf8Error(ref e) => e.description(),
                 ParseError::UnclosedBlockComment => "Unclosed block comment",
+                ParseError::UnderscoreAtBeginning => "Found underscore at the beginning",
                 ParseError::UnexpectedByte(_) => "Unexpected byte",
                 ParseError::TrailingCharacters => "Non-whitespace trailing characters",
 
diff --git a/src/parse.rs b/src/parse.rs
index a6a19bc0..e1358e35 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -6,7 +6,7 @@ use std::str::{FromStr, from_utf8, from_utf8_unchecked};
 
 use de::{Error, ParseError, Result};
 
-const DIGITS: &[u8] = b"0123456789ABCDEFabcdef";
+const DIGITS: &[u8] = b"0123456789ABCDEFabcdef_";
 const FLOAT_CHARS: &[u8] = b"0123456789.+-eE";
 const IDENT_FIRST: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_";
 const IDENT_CHAR: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789";
@@ -486,8 +486,20 @@ impl<'a> Bytes<'a> {
             return self.err(ParseError::ExpectedInteger);
         }
 
+        let tmp;
+        let mut s = unsafe { from_utf8_unchecked(&self.bytes[0..num_bytes]) };
+
+        if s.as_bytes()[0] == b'_' {
+            return self.err(ParseError::UnderscoreAtBeginning);
+        }
+
+        if s.contains('_') {
+            tmp = s.replace('_', "");
+            s = &tmp;
+        }
+
         let res = Num::from_str(
-            unsafe { from_utf8_unchecked(&self.bytes[0..num_bytes]) },
+            s,
             base,
         ).map_err(|_| self.error(ParseError::ExpectedInteger));
 


Test patch:
diff --git a/src/de/tests.rs b/src/de/tests.rs
index 152c2410..256142cf 100644
--- a/src/de/tests.rs
+++ b/src/de/tests.rs
@@ -292,3 +292,11 @@ fn test_byte_stream() {
         from_str("BytesStruct( small:[1, 2], large:\"AQIDBA==\" )"),
     );
 }
+
+#[test]
+fn test_numbers() {
+    assert_eq!(
+        Ok(vec![1234, 12345, 123456, 1234567, 555_555]),
+        from_str("[1_234, 12_345, 1_2_3_4_5_6, 1_234_567, 5_55_55_5]"),
+    );
+}