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