rust/hedgewars-network-protocol/src/parser.rs
changeset 16011 cf580d9ff7ef
parent 15852 ea459da15b30
child 16016 b26c3497ea85
equal deleted inserted replaced
16010:5ba4d3a0c3eb 16011:cf580d9ff7ef
   125         map(tag_no_case(b"YES"), |_| true),
   125         map(tag_no_case(b"YES"), |_| true),
   126         map(tag_no_case(b"NO"), |_| false),
   126         map(tag_no_case(b"NO"), |_| false),
   127     ))(input)
   127     ))(input)
   128 }
   128 }
   129 
   129 
   130 fn opt_arg<'a>(input: &'a [u8]) -> HwResult<'a, Option<String>> {
   130 fn opt_arg(input: &[u8]) -> HwResult<Option<String>> {
   131     alt((
   131     alt((
   132         map(peek(end_of_message), |_| None),
   132         map(peek(end_of_message), |_| None),
   133         map(preceded(tag("\n"), a_line), Some),
   133         map(preceded(tag("\n"), a_line), Some),
   134     ))(input)
   134     ))(input)
   135 }
   135 }
   136 
   136 
   137 fn spaces(input: &[u8]) -> HwResult<&[u8]> {
   137 fn spaces(input: &[u8]) -> HwResult<&[u8]> {
   138     preceded(tag(" "), take_while(|c| c == b' '))(input)
   138     preceded(tag(" "), take_while(|c| c == b' '))(input)
   139 }
   139 }
   140 
   140 
   141 fn opt_space_arg<'a>(input: &'a [u8]) -> HwResult<'a, Option<String>> {
   141 fn opt_space_arg(input: &[u8]) -> HwResult<Option<String>> {
   142     alt((
   142     alt((
   143         map(peek(end_of_message), |_| None),
   143         map(peek(end_of_message), |_| None),
   144         map(preceded(spaces, a_line), Some),
   144         map(preceded(spaces, a_line), Some),
   145     ))(input)
   145     ))(input)
   146 }
   146 }
   182         map(preceded(tag_no_case("MAP"), opt_space_arg), VoteType::Map),
   182         map(preceded(tag_no_case("MAP"), opt_space_arg), VoteType::Map),
   183     ))(input)
   183     ))(input)
   184 }
   184 }
   185 
   185 
   186 fn no_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   186 fn no_arg_message(input: &[u8]) -> HwResult<HwProtocolMessage> {
   187     fn message<'a>(
   187     fn message(
   188         name: &'a str,
   188         name: &str,
   189         msg: HwProtocolMessage,
   189         msg: HwProtocolMessage,
   190     ) -> impl Fn(&'a [u8]) -> HwResult<'a, 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<'a, T, F, G>(
   210     fn message<T, F, G>(
   211         name: &'a str,
   211         name: &str,
   212         parser: F,
   212         parser: F,
   213         constructor: G,
   213         constructor: G,
   214     ) -> impl FnMut(&'a [u8]) -> HwResult<'a, HwProtocolMessage>
   214     ) -> impl FnMut(&[u8]) -> HwResult<HwProtocolMessage>
   215     where
   215     where
   216         F: Fn(&[u8]) -> HwResult<T>,
   216         F: Fn(&[u8]) -> HwResult<T>,
   217         G: Fn(T) -> HwProtocolMessage,
   217         G: Fn(T) -> HwProtocolMessage,
   218     {
   218     {
   219         map(preceded(tag(name), parser), constructor)
   219         map(preceded(tag(name), parser), constructor)
   237         message("CHECKED\nFAIL\n", a_line, CheckedFail),
   237         message("CHECKED\nFAIL\n", a_line, CheckedFail),
   238     ))(input)
   238     ))(input)
   239 }
   239 }
   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<'a>(
   242     fn cmd_no_arg(
   243         name: &'a str,
   243         name: &str,
   244         msg: HwProtocolMessage,
   244         msg: HwProtocolMessage,
   245     ) -> impl Fn(&'a [u8]) -> HwResult<'a, 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<'a, T, F, G>(
   322     fn cfg_single_arg<T, F, G>(
   323         name: &'a str,
   323         name: &str,
   324         parser: F,
   324         parser: F,
   325         constructor: G,
   325         constructor: G,
   326     ) -> impl FnMut(&'a [u8]) -> HwResult<'a, GameCfg>
   326     ) -> impl FnMut(&[u8]) -> HwResult<GameCfg>
   327     where
   327     where
   328         F: Fn(&[u8]) -> HwResult<T>,
   328         F: Fn(&[u8]) -> HwResult<T>,
   329         G: Fn(T) -> GameCfg,
   329         G: Fn(T) -> GameCfg,
   330     {
   330     {
   331         map(preceded(pair(tag(name), newline), parser), constructor)
   331         map(preceded(pair(tag(name), newline), parser), constructor)
   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<'a, T, F, G>(
   524     fn single_arg_message<T, F, G>(
   525         name: &'a str,
   525         name: &str,
   526         parser: F,
   526         parser: F,
   527         constructor: G,
   527         constructor: G,
   528     ) -> impl FnMut(&'a [u8]) -> HwResult<'a, HwServerMessage>
   528     ) -> impl FnMut(&[u8]) -> HwResult<HwServerMessage>
   529     where
   529     where
   530         F: Fn(&[u8]) -> HwResult<T>,
   530         F: Fn(&[u8]) -> HwResult<T>,
   531         G: Fn(T) -> HwServerMessage,
   531         G: Fn(T) -> HwServerMessage,
   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<'a, G>(
   539     fn list_message<G>(
   540         name: &'a str,
   540         name: &str,
   541         constructor: G,
   541         constructor: G,
   542     ) -> impl FnMut(&'a [u8]) -> HwResult<'a, HwServerMessage>
   542     ) -> impl FnMut(&[u8]) -> HwResult<HwServerMessage>
   543     where
   543     where
   544         G: Fn(Vec<String>) -> HwServerMessage,
   544         G: Fn(Vec<String>) -> HwServerMessage,
   545     {
   545     {
   546         map(
   546         map(
   547             preceded(
   547             preceded(
   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<'a, G>(
   558     fn string_and_list_message<G>(
   559         name: &'a str,
   559         name: &str,
   560         constructor: G,
   560         constructor: G,
   561     ) -> impl FnMut(&'a [u8]) -> HwResult<'a, HwServerMessage>
   561     ) -> impl FnMut(&[u8]) -> HwResult<HwServerMessage>
   562     where
   562     where
   563         G: Fn(String, Vec<String>) -> HwServerMessage,
   563         G: Fn(String, Vec<String>) -> HwServerMessage,
   564     {
   564     {
   565         preceded(
   565         preceded(
   566             pair(tag(name), newline),
   566             pair(tag(name), newline),
   575                 move |(name, values)| constructor(name, values.unwrap_or_default()),
   575                 move |(name, values)| constructor(name, values.unwrap_or_default()),
   576             ),
   576             ),
   577         )
   577         )
   578     }
   578     }
   579 
   579 
   580     fn message<'a>(
   580     fn message(
   581         name: &'a str,
   581         name: &str,
   582         msg: HwServerMessage,
   582         msg: HwServerMessage,
   583     ) -> impl Fn(&'a [u8]) -> HwResult<'a, 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'),