rust/hedgewars-server/src/server/haskell.rs
author alfadur
Wed, 20 May 2020 19:38:44 +0300
changeset 15577 7d4f552e317f
parent 15576 3be9c98ae190
child 15578 0b6094660557
permissions -rw-r--r--
parse booleans as well
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
     1
use crate::server::haskell::HaskellValue::Boolean;
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
     2
use nom::{
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
     3
    branch::alt,
15572
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
     4
    bytes::complete::{escaped_transform, is_not, tag, take_while, take_while1},
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
     5
    character::{is_alphanumeric, is_digit, is_space},
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
     6
    combinator::{map, map_res},
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
     7
    multi::separated_list,
15572
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
     8
    sequence::{delimited, pair, preceded, separated_pair},
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
     9
    ExtendInto, IResult,
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
    10
};
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    11
use std::{
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    12
    collections::HashMap,
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    13
    fmt::{Display, Error, Formatter},
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    14
};
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
    15
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
    16
type HaskellResult<'a, T> = IResult<&'a [u8], T>;
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
    17
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
    18
#[derive(Debug, PartialEq)]
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
    19
pub enum HaskellValue {
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
    20
    Boolean(bool),
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    21
    Number(u8),
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    22
    String(String),
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
    23
    Tuple(Vec<HaskellValue>),
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    24
    List(Vec<HaskellValue>),
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    25
    AnonStruct {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    26
        name: String,
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    27
        fields: Vec<HaskellValue>,
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    28
    },
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
    29
    Struct {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
    30
        name: String,
15571
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
    31
        fields: HashMap<String, HaskellValue>,
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
    32
    },
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    33
}
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    34
15576
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    35
impl HaskellValue {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    36
    pub fn to_number(&self) -> Option<u8> {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    37
        match self {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    38
            HaskellValue::Number(value) => Some(*value),
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    39
            _ => None,
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    40
        }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    41
    }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    42
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    43
    pub fn into_number(self) -> Option<u8> {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    44
        match self {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    45
            HaskellValue::Number(value) => Some(value),
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    46
            _ => None,
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    47
        }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    48
    }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    49
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    50
    pub fn to_string(&self) -> Option<&str> {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    51
        match self {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    52
            HaskellValue::String(value) => Some(value),
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    53
            _ => None,
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    54
        }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    55
    }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    56
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    57
    pub fn into_string(self) -> Option<String> {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    58
        match self {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    59
            HaskellValue::String(value) => Some(value),
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    60
            _ => None,
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    61
        }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    62
    }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    63
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    64
    pub fn into_list(self) -> Option<Vec<HaskellValue>> {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    65
        match self {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    66
            HaskellValue::List(items) => Some(items),
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    67
            _ => None,
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    68
        }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    69
    }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    70
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    71
    pub fn into_tuple(self) -> Option<Vec<HaskellValue>> {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    72
        match self {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    73
            HaskellValue::Tuple(items) => Some(items),
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    74
            _ => None,
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    75
        }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    76
    }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    77
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    78
    pub fn into_anon_struct(self) -> Option<(String, Vec<HaskellValue>)> {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    79
        match self {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    80
            HaskellValue::AnonStruct { name, fields } => Some((name, fields)),
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    81
            _ => None,
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    82
        }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    83
    }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    84
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    85
    pub fn into_struct(self) -> Option<(String, HashMap<String, HaskellValue>)> {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    86
        match self {
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    87
            HaskellValue::Struct { name, fields } => Some((name, fields)),
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    88
            _ => None,
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    89
        }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    90
    }
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    91
}
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
    92
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    93
fn write_sequence(
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    94
    f: &mut Formatter<'_>,
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    95
    brackets: &[u8; 2],
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    96
    mut items: std::slice::Iter<HaskellValue>,
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    97
) -> Result<(), Error> {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    98
    write!(f, "{}", brackets[0] as char)?;
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
    99
    while let Some(value) = items.next() {
15576
3be9c98ae190 convert teams from haskell list
alfadur
parents: 15575
diff changeset
   100
        write!(f, "{}", value)?;
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   101
        if !items.as_slice().is_empty() {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   102
            write!(f, ", ")?;
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   103
        }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   104
    }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   105
    if brackets[1] != b'\0' {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   106
        write!(f, "{}", brackets[1] as char)
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   107
    } else {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   108
        Ok(())
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   109
    }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   110
}
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   111
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   112
fn write_text(f: &mut Formatter<'_>, text: &str) -> Result<(), Error> {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   113
    write!(f, "\"")?;
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   114
    for c in text.chars() {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   115
        if c.is_ascii() && !(c as u8).is_ascii_control() {
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   116
            write!(f, "{}", c)?;
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   117
        } else {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   118
            let mut bytes = [0u8; 4];
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   119
            let size = c.encode_utf8(&mut bytes).len();
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   120
            for byte in &bytes[0..size] {
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   121
                write!(f, "\\{:03}", byte)?;
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   122
            }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   123
        }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   124
    }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   125
    write!(f, "\"")
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   126
}
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   127
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   128
impl Display for HaskellValue {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   129
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   130
        match self {
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   131
            HaskellValue::Boolean(value) => write!(f, "{}", if *value { "True" } else { "False" }),
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   132
            HaskellValue::Number(value) => write!(f, "{}", value),
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   133
            HaskellValue::String(value) => write_text(f, value),
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   134
            HaskellValue::Tuple(items) => write_sequence(f, b"()", items.iter()),
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   135
            HaskellValue::List(items) => write_sequence(f, b"[]", items.iter()),
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   136
            HaskellValue::AnonStruct { name, fields } => {
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   137
                write!(f, "{} ", name)?;
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   138
                write_sequence(f, b" \0", fields.iter())
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   139
            }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   140
            HaskellValue::Struct { name, fields } => {
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   141
                write!(f, "{} {{", name)?;
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   142
                let fields = fields.iter().collect::<Vec<_>>();
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   143
                let mut items = fields.iter();
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   144
                while let Some((field_name, value)) = items.next() {
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   145
                    write!(f, "{} = {}", field_name, value)?;
15574
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   146
                    if !items.as_slice().is_empty() {
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   147
                        write!(f, ", ")?;
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   148
                    }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   149
                }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   150
                write!(f, "}}")
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   151
            }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   152
        }
ca5c7c1de985 add haskell literal formatter
alfadur
parents: 15573
diff changeset
   153
    }
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   154
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   155
15571
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   156
fn comma(input: &[u8]) -> HaskellResult<&[u8]> {
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   157
    delimited(take_while(is_space), tag(","), take_while(is_space))(input)
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   158
}
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   159
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   160
fn surrounded<'a, P, O>(
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   161
    prefix: &'static str,
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   162
    suffix: &'static str,
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   163
    parser: P,
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   164
) -> impl Fn(&'a [u8]) -> HaskellResult<'a, O>
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   165
where
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   166
    P: Fn(&'a [u8]) -> HaskellResult<'a, O>,
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   167
{
15571
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   168
    move |input| {
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   169
        delimited(
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   170
            delimited(take_while(is_space), tag(prefix), take_while(is_space)),
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   171
            |i| parser(i),
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   172
            delimited(take_while(is_space), tag(suffix), take_while(is_space)),
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   173
        )(input)
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   174
    }
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   175
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   176
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   177
fn boolean(input: &[u8]) -> HaskellResult<HaskellValue> {
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   178
    map(
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   179
        alt((map(tag("True"), |_| true), map(tag("False"), |_| false))),
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   180
        HaskellValue::Boolean,
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   181
    )(input)
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   182
}
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   183
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   184
fn number_raw(input: &[u8]) -> HaskellResult<u8> {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   185
    use std::str::FromStr;
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   186
    map_res(take_while(is_digit), |s| {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   187
        std::str::from_utf8(s)
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   188
            .map_err(|_| ())
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   189
            .and_then(|s| u8::from_str(s).map_err(|_| ()))
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   190
    })(input)
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   191
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   192
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   193
fn number(input: &[u8]) -> HaskellResult<HaskellValue> {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   194
    map(number_raw, HaskellValue::Number)(input)
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   195
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   196
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   197
enum Escape {
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   198
    Empty,
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   199
    Byte(u8),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   200
}
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   201
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   202
impl ExtendInto for Escape {
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   203
    type Item = u8;
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   204
    type Extender = Vec<u8>;
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   205
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   206
    fn new_builder(&self) -> Self::Extender {
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   207
        Vec::new()
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   208
    }
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   209
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   210
    fn extend_into(&self, acc: &mut Self::Extender) {
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   211
        if let Escape::Byte(b) = self {
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   212
            acc.push(*b);
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   213
        }
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   214
    }
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   215
}
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   216
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   217
impl Extend<Escape> for Vec<u8> {
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   218
    fn extend<T: IntoIterator<Item = Escape>>(&mut self, iter: T) {
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   219
        for item in iter {
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   220
            item.extend_into(self);
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   221
        }
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   222
    }
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   223
}
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   224
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   225
fn string_escape(input: &[u8]) -> HaskellResult<Escape> {
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   226
    use Escape::*;
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   227
    alt((
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   228
        map(number_raw, |n| Byte(n)),
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   229
        alt((
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   230
            map(tag("\\"), |_| Byte(b'\\')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   231
            map(tag("\""), |_| Byte(b'\"')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   232
            map(tag("'"), |_| Byte(b'\'')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   233
            map(tag("n"), |_| Byte(b'\n')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   234
            map(tag("r"), |_| Byte(b'\r')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   235
            map(tag("t"), |_| Byte(b'\t')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   236
            map(tag("a"), |_| Byte(b'\x07')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   237
            map(tag("b"), |_| Byte(b'\x08')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   238
            map(tag("v"), |_| Byte(b'\x0B')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   239
            map(tag("f"), |_| Byte(b'\x0C')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   240
            map(tag("&"), |_| Empty),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   241
            map(tag("NUL"), |_| Byte(b'\x00')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   242
            map(tag("SOH"), |_| Byte(b'\x01')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   243
            map(tag("STX"), |_| Byte(b'\x02')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   244
            map(tag("ETX"), |_| Byte(b'\x03')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   245
            map(tag("EOT"), |_| Byte(b'\x04')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   246
            map(tag("ENQ"), |_| Byte(b'\x05')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   247
            map(tag("ACK"), |_| Byte(b'\x06')),
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   248
        )),
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   249
        alt((
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   250
            map(tag("SO"), |_| Byte(b'\x0E')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   251
            map(tag("SI"), |_| Byte(b'\x0F')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   252
            map(tag("DLE"), |_| Byte(b'\x10')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   253
            map(tag("DC1"), |_| Byte(b'\x11')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   254
            map(tag("DC2"), |_| Byte(b'\x12')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   255
            map(tag("DC3"), |_| Byte(b'\x13')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   256
            map(tag("DC4"), |_| Byte(b'\x14')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   257
            map(tag("NAK"), |_| Byte(b'\x15')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   258
            map(tag("SYN"), |_| Byte(b'\x16')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   259
            map(tag("ETB"), |_| Byte(b'\x17')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   260
            map(tag("CAN"), |_| Byte(b'\x18')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   261
            map(tag("EM"), |_| Byte(b'\x19')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   262
            map(tag("SUB"), |_| Byte(b'\x1A')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   263
            map(tag("ESC"), |_| Byte(b'\x1B')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   264
            map(tag("FS"), |_| Byte(b'\x1C')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   265
            map(tag("GS"), |_| Byte(b'\x1D')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   266
            map(tag("RS"), |_| Byte(b'\x1E')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   267
            map(tag("US"), |_| Byte(b'\x1F')),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   268
            map(tag("DEL"), |_| Byte(b'\x7F')),
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   269
        )),
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   270
    ))(input)
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   271
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   272
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   273
fn string_content(mut input: &[u8]) -> HaskellResult<String> {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   274
    map_res(
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   275
        escaped_transform(is_not("\"\\"), '\\', string_escape),
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   276
        |bytes| String::from_utf8(bytes).map_err(|_| ()),
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   277
    )(input)
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   278
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   279
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   280
fn string(input: &[u8]) -> HaskellResult<HaskellValue> {
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   281
    map(
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   282
        delimited(tag("\""), string_content, tag("\"")),
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   283
        HaskellValue::String,
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   284
    )(input)
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   285
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   286
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   287
fn tuple(input: &[u8]) -> HaskellResult<HaskellValue> {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   288
    map(
15571
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   289
        surrounded("(", ")", separated_list(comma, value)),
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   290
        HaskellValue::Tuple,
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   291
    )(input)
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   292
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   293
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   294
fn list(input: &[u8]) -> HaskellResult<HaskellValue> {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   295
    map(
15571
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   296
        surrounded("[", "]", separated_list(comma, value)),
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   297
        HaskellValue::List,
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   298
    )(input)
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   299
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   300
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   301
fn identifier(input: &[u8]) -> HaskellResult<String> {
15572
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   302
    map_res(take_while1(is_alphanumeric), |s| {
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   303
        std::str::from_utf8(s).map_err(|_| ()).map(String::from)
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   304
    })(input)
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   305
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   306
15571
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   307
fn named_field(input: &[u8]) -> HaskellResult<(String, HaskellValue)> {
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   308
    separated_pair(
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   309
        identifier,
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   310
        delimited(take_while(is_space), tag("="), take_while(is_space)),
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   311
        value,
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   312
    )(input)
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   313
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   314
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   315
fn structure(input: &[u8]) -> HaskellResult<HaskellValue> {
15572
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   316
    alt((
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   317
        map(
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   318
            pair(
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   319
                identifier,
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   320
                surrounded("{", "}", separated_list(comma, named_field)),
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   321
            ),
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   322
            |(name, mut fields)| HaskellValue::Struct {
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   323
                name,
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   324
                fields: fields.drain(..).collect(),
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   325
            },
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   326
        ),
15572
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   327
        map(
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   328
            pair(
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   329
                identifier,
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   330
                preceded(
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   331
                    take_while(is_space),
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   332
                    separated_list(take_while1(is_space), value),
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   333
                ),
15572
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   334
            ),
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   335
            |(name, mut fields)| HaskellValue::AnonStruct {
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   336
                name: name.clone(),
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   337
                fields,
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   338
            },
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   339
        ),
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   340
    ))(input)
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   341
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   342
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   343
fn value(input: &[u8]) -> HaskellResult<HaskellValue> {
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   344
    alt((boolean, number, string, tuple, list, structure))(input)
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   345
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   346
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   347
#[inline]
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   348
pub fn parse(input: &[u8]) -> HaskellResult<HaskellValue> {
15571
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   349
    delimited(take_while(is_space), value, take_while(is_space))(input)
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   350
}
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   351
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   352
mod test {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   353
    use super::*;
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   354
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   355
    #[test]
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   356
    fn terminals() {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   357
        use HaskellValue::*;
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   358
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   359
        matches!(number(b"127"), Ok((_, Number(127))));
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   360
        matches!(number(b"adas"), Err(nom::Err::Error(_)));
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   361
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   362
        assert_eq!(
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   363
            string(b"\"Hail \\240\\159\\166\\148!\""),
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   364
            Ok((&b""[..], String("Hail \u{1f994}!".to_string())))
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   365
        );
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   366
    }
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   367
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   368
    #[test]
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   369
    fn sequences() {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   370
        use HaskellValue::*;
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   371
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   372
        let value = Tuple(vec![
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   373
            Number(64),
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   374
            String("text\t1".to_string()),
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   375
            List(vec![Number(1), Number(2), Number(3)]),
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   376
        ]);
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   377
15575
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   378
        assert_eq!(
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   379
            tuple(b"(64, \"text\\t1\", [1 , 2, 3])"),
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   380
            Ok((&b""[..], value))
a2e78f5907cc improve escapes handling
alfadur
parents: 15574
diff changeset
   381
        );
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   382
    }
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   383
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   384
    #[test]
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   385
    fn structures() {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   386
        use HaskellValue::*;
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   387
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   388
        let value = Struct {
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   389
            name: "Hog".to_string(),
15571
ae6b09ae4dcc add whitespace handling
alfadur
parents: 15570
diff changeset
   390
            fields: vec![
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   391
                ("name".to_string(), String("\u{1f994}".to_string())),
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   392
                ("health".to_string(), Number(100)),
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   393
            ]
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   394
            .drain(..)
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   395
            .collect(),
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   396
        };
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   397
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   398
        assert_eq!(
15572
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   399
            structure(b"Hog {name = \"\\240\\159\\166\\148\", health = 100}"),
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   400
            Ok((&b""[..], value))
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   401
        );
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   402
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   403
        let value = AnonStruct {
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   404
            name: "Hog".to_string(),
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   405
            fields: vec![Boolean(true), Number(100), String("\u{1f994}".to_string())],
15572
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   406
        };
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   407
9a333e4e3b50 parse anonymous fields
alfadur
parents: 15571
diff changeset
   408
        assert_eq!(
15577
7d4f552e317f parse booleans as well
alfadur
parents: 15576
diff changeset
   409
            structure(b"Hog True 100 \"\\240\\159\\166\\148\""),
15570
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   410
            Ok((&b""[..], value))
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   411
        );
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   412
    }
d524b7450576 add haskell literal parser
alfadur
parents:
diff changeset
   413
}