add whitespace handling
authoralfadur
Mon, 18 May 2020 22:04:38 +0300
changeset 15571 ae6b09ae4dcc
parent 15570 d524b7450576
child 15572 9a333e4e3b50
add whitespace handling
rust/hedgewars-server/src/server/haskell.rs
--- a/rust/hedgewars-server/src/server/haskell.rs	Mon May 18 21:17:46 2020 +0300
+++ b/rust/hedgewars-server/src/server/haskell.rs	Mon May 18 22:04:38 2020 +0300
@@ -1,14 +1,11 @@
-use nom::character::is_alphanumeric;
 use nom::{
     branch::alt,
-    bytes::{
-        complete::tag,
-        complete::take_while,
-        complete::{escaped_transform, is_not},
-    },
+    bytes::complete::{escaped_transform, is_not, tag, take_while},
     character::is_digit,
+    character::{is_alphanumeric, is_space},
     combinator::{map, map_res},
     multi::separated_list,
+    sequence::separated_pair,
     sequence::{delimited, pair},
     IResult,
 };
@@ -24,10 +21,14 @@
     Number(u8),
     Struct {
         name: String,
-        values: HashMap<String, HaskellValue>,
+        fields: HashMap<String, HaskellValue>,
     },
 }
 
+fn comma(input: &[u8]) -> HaskellResult<&[u8]> {
+    delimited(take_while(is_space), tag(","), take_while(is_space))(input)
+}
+
 fn surrounded<'a, P, O>(
     prefix: &'static str,
     suffix: &'static str,
@@ -36,7 +37,13 @@
 where
     P: Fn(&'a [u8]) -> HaskellResult<'a, O>,
 {
-    move |input| delimited(tag(prefix), |i| parser(i), tag(suffix))(input)
+    move |input| {
+        delimited(
+            delimited(take_while(is_space), tag(prefix), take_while(is_space)),
+            |i| parser(i),
+            delimited(take_while(is_space), tag(suffix), take_while(is_space)),
+        )(input)
+    }
 }
 
 fn number_raw(input: &[u8]) -> HaskellResult<u8> {
@@ -52,14 +59,6 @@
     map(number_raw, HaskellValue::Number)(input)
 }
 
-fn read_string(input: &[u8]) -> HaskellResult<String> {
-    Ok((input, String::new()))
-}
-
-fn raw_string_part(input: &[u8]) -> HaskellResult<&[u8]> {
-    take_while(|c| !b"\"\\".contains(&c))(input)
-}
-
 const BYTES: &[u8] = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
 
 fn string_escape(input: &[u8]) -> HaskellResult<&[u8]> {
@@ -122,14 +121,14 @@
 
 fn tuple(input: &[u8]) -> HaskellResult<HaskellValue> {
     map(
-        surrounded("(", ")", separated_list(tag(","), value)),
+        surrounded("(", ")", separated_list(comma, value)),
         HaskellValue::Tuple,
     )(input)
 }
 
 fn list(input: &[u8]) -> HaskellResult<HaskellValue> {
     map(
-        surrounded("[", "]", separated_list(tag(","), value)),
+        surrounded("[", "]", separated_list(comma, value)),
         HaskellValue::List,
     )(input)
 }
@@ -140,23 +139,23 @@
     })(input)
 }
 
-fn property() -> impl Fn(&[u8]) -> HaskellResult<(String, HaskellValue)> {
-    |input| {
-        let (input, name) = identifier(input)?;
-        let (input, _) = tag("=")(input)?;
-        value(input).map(|(i, value)| (i, (name, value)))
-    }
+fn named_field(input: &[u8]) -> HaskellResult<(String, HaskellValue)> {
+    separated_pair(
+        identifier,
+        delimited(take_while(is_space), tag("="), take_while(is_space)),
+        value,
+    )(input)
 }
 
 fn structure(input: &[u8]) -> HaskellResult<HaskellValue> {
     map(
         pair(
             identifier,
-            surrounded("{", "}", separated_list(tag(","), property())),
+            surrounded("{", "}", separated_list(comma, named_field)),
         ),
-        |(name, mut values)| HaskellValue::Struct {
+        |(name, mut fields)| HaskellValue::Struct {
             name,
-            values: values.drain(..).collect(),
+            fields: fields.drain(..).collect(),
         },
     )(input)
 }
@@ -167,7 +166,7 @@
 
 #[inline]
 pub fn parse(input: &[u8]) -> HaskellResult<HaskellValue> {
-    value(input)
+    delimited(take_while(is_space), value, take_while(is_space))(input)
 }
 
 mod test {
@@ -196,7 +195,7 @@
             List(vec![Number(1), Number(2), Number(3)]),
         ]);
 
-        assert_eq!(tuple(b"(64,\"text\",[1,2,3])"), Ok((&b""[..], value)));
+        assert_eq!(tuple(b"(64, \"text\", [1 , 2, 3])"), Ok((&b""[..], value)));
     }
 
     #[test]
@@ -205,7 +204,7 @@
 
         let value = Struct {
             name: "Hog".to_string(),
-            values: vec![
+            fields: vec![
                 ("name".to_string(), String("\u{1f994}".to_string())),
                 ("health".to_string(), Number(100)),
             ]
@@ -214,7 +213,7 @@
         };
 
         assert_eq!(
-            structure(b"Hog{name=\"\\240\\159\\166\\148\",health=100}"),
+            structure(b"Hog {name = \"\\240\\159\\166\\148\",health = 100}"),
             Ok((&b""[..], value))
         );
     }