rust/hedgewars-network-protocol/src/parser.rs
changeset 16016 b26c3497ea85
parent 16011 cf580d9ff7ef
child 16026 7c8697fa019f
equal deleted inserted replaced
16015:cd8392e52165 16016:b26c3497ea85
    12     character::complete::{newline, not_line_ending},
    12     character::complete::{newline, not_line_ending},
    13     combinator::{map, peek},
    13     combinator::{map, peek},
    14     error::{ErrorKind, ParseError},
    14     error::{ErrorKind, ParseError},
    15     multi::separated_list0,
    15     multi::separated_list0,
    16     sequence::{delimited, pair, preceded, terminated, tuple},
    16     sequence::{delimited, pair, preceded, terminated, tuple},
    17     Err, IResult,
    17     Err, IResult, Parser
    18 };
    18 };
    19 
    19 
    20 use std::{
    20 use std::{
    21     num::ParseIntError,
    21     num::ParseIntError,
    22     str,
    22     str,
   185 
   185 
   186 fn no_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   186 fn no_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   187     fn message(
   187     fn message(
   188         name: &str,
   188         name: &str,
   189         msg: HwProtocolMessage,
   189         msg: HwProtocolMessage,
   190     ) -> impl Fn(&[u8]) -> HwResult<HwProtocolMessage> {
   190     ) -> impl Fn(&[u8]) -> HwResult<HwProtocolMessage> + '_ {
   191         move |i| map(tag(name), |_| msg.clone())(i)
   191         move |i| map(tag(name), |_| msg.clone())(i)
   192     }
   192     }
   193 
   193 
   194     alt((
   194     alt((
   195         message("PING", Ping),
   195         message("PING", Ping),
   205         message("READY", CheckerReady),
   205         message("READY", CheckerReady),
   206     ))(input)
   206     ))(input)
   207 }
   207 }
   208 
   208 
   209 fn single_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   209 fn single_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   210     fn message<T, F, G>(
   210     fn message<'a, T: 'a, F, G>(
   211         name: &str,
   211         name: &'a str,
   212         parser: F,
   212         parser: F,
   213         constructor: G,
   213         constructor: G,
   214     ) -> impl FnMut(&[u8]) -> HwResult<HwProtocolMessage>
   214     ) -> impl FnMut(&'a [u8]) -> HwResult<HwProtocolMessage> + '_
   215     where
   215     where
   216         F: Fn(&[u8]) -> HwResult<T>,
   216         F: Parser<&'a [u8], T, HwProtocolError> + 'a,
   217         G: Fn(T) -> HwProtocolMessage,
   217         G: FnMut(T) -> HwProtocolMessage + 'a
   218     {
   218     {
   219         map(preceded(tag(name), parser), constructor)
   219         map(preceded(tag(name), parser), constructor)
   220     }
   220     }
   221 
   221 
   222     alt((
   222     alt((
   240 
   240 
   241 fn cmd_message<'a>(input: &'a [u8]) -> HwResult<'a, HwProtocolMessage> {
   241 fn cmd_message<'a>(input: &'a [u8]) -> HwResult<'a, HwProtocolMessage> {
   242     fn cmd_no_arg(
   242     fn cmd_no_arg(
   243         name: &str,
   243         name: &str,
   244         msg: HwProtocolMessage,
   244         msg: HwProtocolMessage,
   245     ) -> impl Fn(&[u8]) -> HwResult<HwProtocolMessage> {
   245     ) -> impl Fn(&[u8]) -> HwResult<HwProtocolMessage> + '_ {
   246         move |i| map(tag_no_case(name), |_| msg.clone())(i)
   246         move |i| map(tag_no_case(name), |_| msg.clone())(i)
   247     }
   247     }
   248 
   248 
   249     fn cmd_single_arg<'a, T, F, G>(
   249     fn cmd_single_arg<'a, T, F, G>(
   250         name: &'a str,
   250         name: &'a str,
   317         )),
   317         )),
   318     )(input)
   318     )(input)
   319 }
   319 }
   320 
   320 
   321 fn config_message<'a>(input: &'a [u8]) -> HwResult<'a, HwProtocolMessage> {
   321 fn config_message<'a>(input: &'a [u8]) -> HwResult<'a, HwProtocolMessage> {
   322     fn cfg_single_arg<T, F, G>(
   322     fn cfg_single_arg<'a, T: 'a, F, G>(
   323         name: &str,
   323         name: &'a str,
   324         parser: F,
   324         parser: F,
   325         constructor: G,
   325         constructor: G,
   326     ) -> impl FnMut(&[u8]) -> HwResult<GameCfg>
   326     ) -> impl FnMut(&'a [u8]) -> HwResult<GameCfg> + '_
   327     where
   327     where
   328         F: Fn(&[u8]) -> HwResult<T>,
   328         F: Parser<&'a [u8], T, HwProtocolError> + 'a,
   329         G: Fn(T) -> GameCfg,
   329         G: Fn(T) -> GameCfg + 'a,
   330     {
   330     {
   331         map(preceded(pair(tag(name), newline), parser), constructor)
   331         map(preceded(pair(tag(name), newline), parser), constructor)
   332     }
   332     }
   333 
   333 
   334     let (i, cfg) = preceded(
   334     let (i, cfg) = preceded(
   519 }
   519 }
   520 
   520 
   521 pub fn server_message(input: &[u8]) -> HwResult<HwServerMessage> {
   521 pub fn server_message(input: &[u8]) -> HwResult<HwServerMessage> {
   522     use HwServerMessage::*;
   522     use HwServerMessage::*;
   523 
   523 
   524     fn single_arg_message<T, F, G>(
   524     fn single_arg_message<'a, T: 'a, F, G>(
   525         name: &str,
   525         name: &'a str,
   526         parser: F,
   526         parser: F,
   527         constructor: G,
   527         constructor: G,
   528     ) -> impl FnMut(&[u8]) -> HwResult<HwServerMessage>
   528     ) -> impl FnMut(&'a [u8]) -> HwResult<HwServerMessage> + '_
   529     where
   529     where
   530         F: Fn(&[u8]) -> HwResult<T>,
   530         F: Parser<&'a [u8], T, HwProtocolError> + 'a,
   531         G: Fn(T) -> HwServerMessage,
   531         G: Fn(T) -> HwServerMessage + 'a,
   532     {
   532     {
   533         map(
   533         map(
   534             preceded(terminated(tag(name), newline), parser),
   534             preceded(terminated(tag(name), newline), parser),
   535             constructor,
   535             constructor,
   536         )
   536         )
   537     }
   537     }
   538 
   538 
   539     fn list_message<G>(
   539     fn list_message<'a, G>(
   540         name: &str,
   540         name: &'a str,
   541         constructor: G,
   541         constructor: G,
   542     ) -> impl FnMut(&[u8]) -> HwResult<HwServerMessage>
   542     ) -> impl FnMut(&'a [u8]) -> HwResult<HwServerMessage> + '_
   543     where
   543     where
   544         G: Fn(Vec<String>) -> HwServerMessage,
   544         G: Fn(Vec<String>) -> HwServerMessage + 'a,
   545     {
   545     {
   546         map(
   546         map(
   547             preceded(
   547             preceded(
   548                 tag(name),
   548                 tag(name),
   549                 alt((
   549                 alt((
   553             ),
   553             ),
   554             move |values| constructor(values.unwrap_or_default()),
   554             move |values| constructor(values.unwrap_or_default()),
   555         )
   555         )
   556     }
   556     }
   557 
   557 
   558     fn string_and_list_message<G>(
   558     fn string_and_list_message<'a, G>(
   559         name: &str,
   559         name: &'a str,
   560         constructor: G,
   560         constructor: G,
   561     ) -> impl FnMut(&[u8]) -> HwResult<HwServerMessage>
   561     ) -> impl FnMut(&'a [u8]) -> HwResult<HwServerMessage> + '_
   562     where
   562     where
   563         G: Fn(String, Vec<String>) -> HwServerMessage,
   563         G: Fn(String, Vec<String>) -> HwServerMessage + 'a,
   564     {
   564     {
   565         preceded(
   565         preceded(
   566             pair(tag(name), newline),
   566             pair(tag(name), newline),
   567             map(
   567             map(
   568                 pair(
   568                 pair(
   578     }
   578     }
   579 
   579 
   580     fn message(
   580     fn message(
   581         name: &str,
   581         name: &str,
   582         msg: HwServerMessage,
   582         msg: HwServerMessage,
   583     ) -> impl Fn(&[u8]) -> HwResult<HwServerMessage> {
   583     ) -> impl Fn(&[u8]) -> HwResult<HwServerMessage> + '_ {
   584         move |i| map(tag(name), |_| msg.clone())(i)
   584         move |i| map(tag(name), |_| msg.clone())(i)
   585     }
   585     }
   586 
   586 
   587     delimited(
   587     delimited(
   588         take_while(|c| c == b'\n'),
   588         take_while(|c| c == b'\n'),