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