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'), |