rust/hedgewars-engine-messages/src/parser.rs
author unC0Rr
Sat, 28 Sep 2024 22:27:13 +0200
changeset 16066 2b4f361e3891
parent 16011 cf580d9ff7ef
permissions -rw-r--r--
Wrap chat lines into div
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
     1
use std::str;
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
     2
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
     3
use nom::branch::alt;
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
     4
use nom::bytes::streaming::*;
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
     5
use nom::combinator::*;
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
     6
use nom::error::{ErrorKind, ParseError};
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
     7
use nom::multi::*;
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
     8
use nom::number::streaming::*;
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
     9
use nom::sequence::{pair, preceded, terminated, tuple};
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    10
use nom::{Err, IResult, Parser};
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    11
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
    12
use crate::messages::{
14235
77b95406631e Implement more of parsing, start implementation of engine messages rendering
unC0Rr
parents: 14232
diff changeset
    13
    ConfigEngineMessage::*, EngineMessage::*, KeystrokeAction::*, SyncedEngineMessage::*,
14281
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
    14
    UnorderedEngineMessage::*, *,
14235
77b95406631e Implement more of parsing, start implementation of engine messages rendering
unC0Rr
parents: 14232
diff changeset
    15
};
14231
1c55c54013c4 Recognize timestamps
unC0Rr
parents: 14230
diff changeset
    16
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    17
fn eof_slice<I>(i: I) -> IResult<I, I>
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    18
where
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    19
    I: nom::InputLength + Clone,
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    20
{
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    21
    if i.input_len() == 0 {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    22
        Ok((i.clone(), i))
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    23
    } else {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    24
        Err(Err::Error(nom::error::Error::new(i, ErrorKind::Eof)))
14232
0f7b92397b9e Parse some synced messages, tests
unC0Rr
parents: 14231
diff changeset
    25
    }
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    26
}
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    27
fn unrecognized_message(input: &[u8]) -> IResult<&[u8], EngineMessage> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    28
    map(rest, |i: &[u8]| Unknown(i.to_owned()))(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    29
}
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
    30
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    31
fn string_tail(input: &[u8]) -> IResult<&[u8], String> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    32
    map_res(rest, str::from_utf8)(input).map(|(i, s)| (i, s.to_owned()))
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    33
}
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
    34
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    35
fn length_without_timestamp(input: &[u8]) -> IResult<&[u8], usize> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    36
    map_opt(rest_len, |l| if l > 2 { Some(l - 2) } else { None })(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    37
}
14231
1c55c54013c4 Recognize timestamps
unC0Rr
parents: 14230
diff changeset
    38
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    39
fn synced_message(input: &[u8]) -> IResult<&[u8], SyncedEngineMessage> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    40
    alt((
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    41
        alt((
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    42
            map(tag(b"L"), |_| Left(Press)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    43
            map(tag(b"l"), |_| Left(Release)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    44
            map(tag(b"R"), |_| Right(Press)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    45
            map(tag(b"r"), |_| Right(Release)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    46
            map(tag(b"U"), |_| Up(Press)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    47
            map(tag(b"u"), |_| Up(Release)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    48
            map(tag(b"D"), |_| Down(Press)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    49
            map(tag(b"d"), |_| Down(Release)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    50
            map(tag(b"Z"), |_| Precise(Press)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    51
            map(tag(b"z"), |_| Precise(Release)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    52
            map(tag(b"A"), |_| Attack(Press)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    53
            map(tag(b"a"), |_| Attack(Release)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    54
            map(tag(b"N"), |_| NextTurn),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    55
            map(tag(b"j"), |_| LongJump),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    56
            map(tag(b"J"), |_| HighJump),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    57
            map(tag(b"S"), |_| Switch),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    58
        )),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    59
        alt((
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    60
            map(tag(b","), |_| Skip),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    61
            map(tag(b"1"), |_| Timer(1)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    62
            map(tag(b"2"), |_| Timer(2)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    63
            map(tag(b"3"), |_| Timer(3)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    64
            map(tag(b"4"), |_| Timer(4)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    65
            map(tag(b"5"), |_| Timer(5)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    66
            map(tuple((tag(b"p"), be_i24, be_i24)), |(_, x, y)| Put(x, y)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    67
            map(tuple((tag(b"P"), be_i24, be_i24)), |(_, x, y)| {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    68
                CursorMove(x, y)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    69
            }),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    70
            map(preceded(tag(b"f"), string_tail), TeamControlLost),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    71
            map(preceded(tag(b"g"), string_tail), TeamControlGained),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    72
            map(preceded(tag(b"t"), be_u8), Taunt),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    73
            map(preceded(tag(b"w"), be_u8), SetWeapon),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    74
            map(preceded(tag(b"~"), be_u8), Slot),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    75
            map(tag(b"+"), |_| Heartbeat),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    76
        )),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    77
    ))(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    78
}
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
    79
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    80
fn unsynced_message(input: &[u8]) -> IResult<&[u8], UnsyncedEngineMessage> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    81
    alt((
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    82
        map(
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    83
            preceded(tag(b"F"), string_tail),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    84
            UnsyncedEngineMessage::TeamControlLost,
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    85
        ),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    86
        map(
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    87
            preceded(tag(b"G"), string_tail),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    88
            UnsyncedEngineMessage::TeamControlGained,
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    89
        ),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    90
        map(
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    91
            preceded(tag(b"h"), string_tail),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    92
            UnsyncedEngineMessage::HogSay,
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    93
        ),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    94
        map(
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    95
            preceded(tag(b"s"), string_tail),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    96
            UnsyncedEngineMessage::ChatMessage,
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    97
        ),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    98
        map(
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
    99
            preceded(tag(b"b"), string_tail),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   100
            UnsyncedEngineMessage::TeamMessage,
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   101
        ),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   102
    ))(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   103
}
14235
77b95406631e Implement more of parsing, start implementation of engine messages rendering
unC0Rr
parents: 14232
diff changeset
   104
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   105
fn unordered_message(input: &[u8]) -> IResult<&[u8], UnorderedEngineMessage> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   106
    alt((
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   107
        map(tag(b"?"), |_| Ping),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   108
        map(tag(b"!"), |_| Pong),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   109
        map(preceded(tag(b"E"), string_tail), Error),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   110
        map(preceded(tag(b"W"), string_tail), Warning),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   111
        map(preceded(tag(b"M"), string_tail), GameSetupChecksum),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   112
        map(tag(b"o"), |_| StopSyncing),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   113
        map(tag(b"I"), |_| PauseToggled),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   114
    ))(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   115
}
14232
0f7b92397b9e Parse some synced messages, tests
unC0Rr
parents: 14231
diff changeset
   116
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   117
fn config_message(input: &[u8]) -> IResult<&[u8], ConfigEngineMessage> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   118
    alt((
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   119
        map(tag(b"C"), |_| ConfigRequest),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   120
        map(preceded(tag(b"eseed "), string_tail), SetSeed),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   121
        map(preceded(tag(b"e$feature_size "), string_tail), |s| {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   122
            SetFeatureSize(s.parse().unwrap_or_default())
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   123
        }),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   124
    ))(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   125
}
14231
1c55c54013c4 Recognize timestamps
unC0Rr
parents: 14230
diff changeset
   126
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   127
fn timestamped_message(input: &[u8]) -> IResult<&[u8], (SyncedEngineMessage, u16)> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   128
    terminated(pair(synced_message, be_u16), eof_slice)(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   129
}
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   130
fn unwrapped_message(input: &[u8]) -> IResult<&[u8], EngineMessage> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   131
    alt((
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   132
        map(timestamped_message, |(m, t)| {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   133
            EngineMessage::Synced(m, t as u32)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   134
        }),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   135
        map(tag(b"#"), |_| Synced(TimeWrap, 65535u32)),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   136
        map(unordered_message, Unordered),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   137
        map(unsynced_message, Unsynced),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   138
        map(config_message, Config),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   139
        unrecognized_message,
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   140
    ))(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   141
}
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
   142
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   143
fn length_specifier(input: &[u8]) -> IResult<&[u8], u16> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   144
    alt((
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   145
        verify(map(take(1usize), |a: &[u8]| a[0] as u16), |&l| l < 64),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   146
        map(take(2usize), |a: &[u8]| {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   147
            (a[0] as u16 - 64) * 256 + a[1] as u16 + 64
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   148
        }),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   149
    ))(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   150
}
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
   151
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   152
fn empty_message(input: &[u8]) -> IResult<&[u8], EngineMessage> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   153
    map(tag(b"\0"), |_| Empty)(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   154
}
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   155
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   156
fn non_empty_message(input: &[u8]) -> IResult<&[u8], EngineMessage> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   157
    map_parser(length_data(length_specifier), unwrapped_message)(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   158
}
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
   159
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   160
fn message(input: &[u8]) -> IResult<&[u8], EngineMessage> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   161
    alt((empty_message, non_empty_message))(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   162
}
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   163
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   164
pub fn extract_messages(input: &[u8]) -> IResult<&[u8], Vec<EngineMessage>> {
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   165
    many0(complete(message))(input)
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   166
}
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
   167
14281
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   168
pub fn extract_message(buf: &[u8]) -> Option<(usize, EngineMessage)> {
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   169
    let parse_result = message(buf);
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   170
    match parse_result {
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   171
        Ok((tail, msg)) => {
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   172
            let consumed = buf.len() - tail.len();
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   173
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   174
            Some((consumed, msg))
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   175
        }
14281
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   176
        Err(Err::Incomplete(_)) => None,
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   177
        Err(Err::Error(_)) | Err(Err::Failure(_)) => unreachable!(),
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   178
    }
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   179
}
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   180
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   181
#[cfg(test)]
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   182
mod tests {
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   183
    use crate::messages::UnsyncedEngineMessage::*;
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   184
    use crate::parser::*;
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
   185
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   186
    #[test]
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   187
    fn parse_length() {
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   188
        assert_eq!(length_specifier(b"\x01"), Ok((&b""[..], 1)));
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   189
        assert_eq!(length_specifier(b"\x00"), Ok((&b""[..], 0)));
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   190
        assert_eq!(length_specifier(b"\x3f"), Ok((&b""[..], 63)));
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   191
        assert_eq!(length_specifier(b"\x40\x00"), Ok((&b""[..], 64)));
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   192
        assert_eq!(
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   193
            length_specifier(b"\xff\xff"),
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   194
            Ok((&b""[..], EngineMessage::MAX_LEN))
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   195
        );
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   196
    }
14281
f0c0d2d217c3 IPC implementation
unC0Rr
parents: 14276
diff changeset
   197
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   198
    #[test]
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   199
    fn parse_synced_messages() {
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   200
        assert_eq!(
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   201
            message(b"\x03L\x01\x02"),
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   202
            Ok((&b""[..], Synced(Left(Press), 258)))
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   203
        );
14275
9f4d75fa4a2c Parse and render more messages
unC0Rr
parents: 14235
diff changeset
   204
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   205
        assert_eq!(message(b"\x01#"), Ok((&b""[..], Synced(TimeWrap, 65535))));
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   206
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   207
        assert_eq!(
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   208
            message(&vec![9, b'p', 255, 133, 151, 1, 0, 2, 0, 0]),
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   209
            Ok((&b""[..], Synced(Put(-31337, 65538), 0)))
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   210
        );
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   211
    }
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
   212
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   213
    #[test]
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   214
    fn parse_unsynced_messages() {
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   215
        assert_eq!(
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   216
            message(b"\x06shello"),
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   217
            Ok((&b""[..], Unsynced(ChatMessage(String::from("hello")))))
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   218
        );
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   219
    }
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
   220
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   221
    #[test]
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   222
    fn parse_incorrect_messages() {
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   223
        assert_eq!(message(b"\x00"), Ok((&b""[..], Empty)));
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   224
        assert_eq!(message(b"\x01\x00"), Ok((&b""[..], Unknown(vec![0]))));
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   225
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   226
        // garbage after correct message
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   227
        assert_eq!(
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   228
            message(b"\x04La\x01\x02"),
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   229
            Ok((&b""[..], Unknown(vec![76, 97, 1, 2])))
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   230
        );
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   231
    }
14232
0f7b92397b9e Parse some synced messages, tests
unC0Rr
parents: 14231
diff changeset
   232
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   233
    #[test]
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   234
    fn parse_config_messages() {
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   235
        assert_eq!(message(b"\x01C"), Ok((&b""[..], Config(ConfigRequest))));
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   236
    }
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
   237
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   238
    #[test]
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   239
    fn parse_test_general() {
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   240
        assert_eq!(string_tail(b"abc"), Ok((&b""[..], String::from("abc"))));
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   241
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   242
        assert_eq!(extract_message(b"\x02#"), None);
16011
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   243
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   244
        assert_eq!(synced_message(b"L"), Ok((&b""[..], Left(Press))));
cf580d9ff7ef Modernize engine protocol parser
unC0Rr
parents: 15831
diff changeset
   245
15305
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   246
        assert_eq!(
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   247
            extract_message(b"\x01#"),
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   248
            Some((2, Synced(TimeWrap, 65535)))
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   249
        );
ae8e14d14596 Move messages queue to hedgewars-engine-messages lib
unc0rr
parents: 15285
diff changeset
   250
    }
14230
ab1ef7074e07 Rearrange code
unC0Rr
parents:
diff changeset
   251
}