rust/hedgewars-server/src/server/haskell.rs
changeset 15599 7d4f552e317f
parent 15598 3be9c98ae190
child 15600 0b6094660557
--- a/rust/hedgewars-server/src/server/haskell.rs	Tue May 19 19:26:48 2020 +0300
+++ b/rust/hedgewars-server/src/server/haskell.rs	Wed May 20 19:38:44 2020 +0300
@@ -1,3 +1,4 @@
+use crate::server::haskell::HaskellValue::Boolean;
 use nom::{
     branch::alt,
     bytes::complete::{escaped_transform, is_not, tag, take_while, take_while1},
@@ -12,10 +13,11 @@
     fmt::{Display, Error, Formatter},
 };
 
-type HaskellResult<'a, T> = IResult<&'a [u8], T, ()>;
+type HaskellResult<'a, T> = IResult<&'a [u8], T>;
 
 #[derive(Debug, PartialEq)]
 pub enum HaskellValue {
+    Boolean(bool),
     Number(u8),
     String(String),
     Tuple(Vec<HaskellValue>),
@@ -126,6 +128,7 @@
 impl Display for HaskellValue {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
         match self {
+            HaskellValue::Boolean(value) => write!(f, "{}", if *value { "True" } else { "False" }),
             HaskellValue::Number(value) => write!(f, "{}", value),
             HaskellValue::String(value) => write_text(f, value),
             HaskellValue::Tuple(items) => write_sequence(f, b"()", items.iter()),
@@ -171,6 +174,13 @@
     }
 }
 
+fn boolean(input: &[u8]) -> HaskellResult<HaskellValue> {
+    map(
+        alt((map(tag("True"), |_| true), map(tag("False"), |_| false))),
+        HaskellValue::Boolean,
+    )(input)
+}
+
 fn number_raw(input: &[u8]) -> HaskellResult<u8> {
     use std::str::FromStr;
     map_res(take_while(is_digit), |s| {
@@ -268,7 +278,10 @@
 }
 
 fn string(input: &[u8]) -> HaskellResult<HaskellValue> {
-    map(surrounded("\"", "\"", string_content), HaskellValue::String)(input)
+    map(
+        delimited(tag("\""), string_content, tag("\"")),
+        HaskellValue::String,
+    )(input)
 }
 
 fn tuple(input: &[u8]) -> HaskellResult<HaskellValue> {
@@ -314,7 +327,10 @@
         map(
             pair(
                 identifier,
-                preceded(take_while1(is_space), separated_list(comma, value)),
+                preceded(
+                    take_while(is_space),
+                    separated_list(take_while1(is_space), value),
+                ),
             ),
             |(name, mut fields)| HaskellValue::AnonStruct {
                 name: name.clone(),
@@ -325,7 +341,7 @@
 }
 
 fn value(input: &[u8]) -> HaskellResult<HaskellValue> {
-    alt((number, string, tuple, list, structure))(input)
+    alt((boolean, number, string, tuple, list, structure))(input)
 }
 
 #[inline]
@@ -341,7 +357,7 @@
         use HaskellValue::*;
 
         matches!(number(b"127"), Ok((_, Number(127))));
-        matches!(number(b"adas"), Err(nom::Err::Error(())));
+        matches!(number(b"adas"), Err(nom::Err::Error(_)));
 
         assert_eq!(
             string(b"\"Hail \\240\\159\\166\\148!\""),
@@ -386,11 +402,11 @@
 
         let value = AnonStruct {
             name: "Hog".to_string(),
-            fields: vec![Number(100), String("\u{1f994}".to_string())],
+            fields: vec![Boolean(true), Number(100), String("\u{1f994}".to_string())],
         };
 
         assert_eq!(
-            structure(b"Hog 100, \"\\240\\159\\166\\148\""),
+            structure(b"Hog True 100 \"\\240\\159\\166\\148\""),
             Ok((&b""[..], value))
         );
     }