1use crate::{flags::*, types::*, value::*};
2use nom::{
3 self,
4 bytes::streaming::take,
5 combinator::{all_consuming, complete, flat_map, map, map_opt, map_parser, map_res},
6 error::{context, ContextError, ErrorKind, ParseError},
7 multi::fold_many0,
8 number::streaming::{
9 be_f32, be_f64, be_i16, be_i32, be_i64, be_u16, be_u32, be_u64, i8 as be_i8, u8 as be_u8,
10 },
11 sequence::pair,
12 Parser,
13};
14use std::{error, fmt};
15use traits::*;
16
17#[derive(Clone, Debug, Eq, PartialEq)]
19enum VerboseErrorKind {
20 Context(&'static str),
22 Char(char),
24 Nom(ErrorKind),
26}
27
28#[derive(Clone, Debug, PartialEq)]
30pub struct ParserErrors {
31 error: VerboseErrorKind,
32 errors: Option<Vec<VerboseErrorKind>>,
33}
34
35impl ParserErrors {
36 #[cfg(not(feature = "verbose-errors"))]
37 fn init_errors() -> Option<Vec<VerboseErrorKind>> {
38 None
39 }
40 #[cfg(feature = "verbose-errors")]
41 fn init_errors() -> Option<Vec<VerboseErrorKind>> {
42 Some(Vec::new())
43 }
44}
45
46impl<I> ParseError<I> for ParserErrors {
47 fn from_error_kind(_input: I, kind: ErrorKind) -> Self {
48 Self {
49 error: VerboseErrorKind::Nom(kind),
50 errors: Self::init_errors(),
51 }
52 }
53
54 fn append(_input: I, kind: ErrorKind, mut other: Self) -> Self {
55 if let Some(errors) = other.errors.as_mut() {
56 errors.push(VerboseErrorKind::Nom(kind));
57 }
58 other
59 }
60
61 fn from_char(_input: I, c: char) -> Self {
62 Self {
63 error: VerboseErrorKind::Char(c),
64 errors: Self::init_errors(),
65 }
66 }
67}
68
69impl<I> ContextError<I> for ParserErrors {
70 fn add_context(_input: I, ctx: &'static str, mut other: Self) -> Self {
71 if let Some(errors) = other.errors.as_mut() {
72 errors.push(VerboseErrorKind::Context(ctx));
73 }
74 other
75 }
76}
77
78impl<I, E> nom::error::FromExternalError<I, E> for ParserErrors {
79 fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
80 Self::from_error_kind(input, kind)
81 }
82}
83
84impl fmt::Display for ParserErrors {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 write!(f, "Parser error: {:?}", self.error)?;
87 if let Some(errors) = self.errors.as_ref() {
88 for error in errors {
89 writeln!(f)?;
90 write!(f, "\tat {:?}", error)?;
91 }
92 }
93 Ok(())
94 }
95}
96
97impl error::Error for ParserErrors {}
98
99pub type ParserError = nom::Err<ParserErrors>;
101pub type ParserResult<I, T> = Result<(I, T), ParserError>;
103
104pub fn parse_raw_value<I: ParsableInput>(
106 amqp_type: AMQPType,
107) -> impl Parser<I, Output = AMQPValue, Error = ParserErrors> {
108 context("parse_raw_value", move |i| match amqp_type {
109 AMQPType::Boolean => map(parse_boolean, AMQPValue::Boolean).parse(i),
110 AMQPType::ShortShortInt => map(parse_short_short_int, AMQPValue::ShortShortInt).parse(i),
111 AMQPType::ShortShortUInt => map(parse_short_short_uint, AMQPValue::ShortShortUInt).parse(i),
112 AMQPType::ShortInt => map(parse_short_int, AMQPValue::ShortInt).parse(i),
113 AMQPType::ShortUInt => map(parse_short_uint, AMQPValue::ShortUInt).parse(i),
114 AMQPType::LongInt => map(parse_long_int, AMQPValue::LongInt).parse(i),
115 AMQPType::LongUInt => map(parse_long_uint, AMQPValue::LongUInt).parse(i),
116 AMQPType::LongLongInt => map(parse_long_long_int, AMQPValue::LongLongInt).parse(i),
117 AMQPType::LongLongUInt => map(parse_long_long_int, AMQPValue::LongLongInt).parse(i),
119 AMQPType::Float => map(parse_float, AMQPValue::Float).parse(i),
120 AMQPType::Double => map(parse_double, AMQPValue::Double).parse(i),
121 AMQPType::DecimalValue => map(parse_decimal_value, AMQPValue::DecimalValue).parse(i),
122 AMQPType::ShortString => map(parse_short_string, AMQPValue::ShortString).parse(i),
123 AMQPType::LongString => map(parse_long_string, AMQPValue::LongString).parse(i),
124 AMQPType::FieldArray => map(parse_field_array, AMQPValue::FieldArray).parse(i),
125 AMQPType::Timestamp => map(parse_timestamp, AMQPValue::Timestamp).parse(i),
126 AMQPType::FieldTable => map(parse_field_table, AMQPValue::FieldTable).parse(i),
127 AMQPType::ByteArray => map(parse_byte_array, AMQPValue::ByteArray).parse(i),
128 AMQPType::Void => Ok((i, AMQPValue::Void)),
129 })
130}
131
132pub fn parse_value<I: ParsableInput>(i: I) -> ParserResult<I, AMQPValue> {
134 context("parse_value", flat_map(parse_type, parse_raw_value)).parse(i)
135}
136
137pub fn parse_type<I: ParsableInput>(i: I) -> ParserResult<I, AMQPType> {
139 context(
140 "parse_type",
141 map_opt(be_u8, |t| AMQPType::from_id(t as char)),
142 )
143 .parse(i)
144}
145
146pub fn parse_id<I: ParsableInput>(i: I) -> ParserResult<I, ShortUInt> {
148 context("parse_id", parse_short_uint).parse(i)
149}
150
151pub fn parse_boolean<I: ParsableInput>(i: I) -> ParserResult<I, Boolean> {
153 context("parse_boolean", map(be_u8, |b| b != 0)).parse(i)
154}
155
156pub fn parse_short_short_int<I: ParsableInput>(i: I) -> ParserResult<I, ShortShortInt> {
158 context("parse_short_short_int", be_i8).parse(i)
159}
160
161pub fn parse_short_short_uint<I: ParsableInput>(i: I) -> ParserResult<I, ShortShortUInt> {
163 context("parse_short_short_uint", be_u8).parse(i)
164}
165
166pub fn parse_short_int<I: ParsableInput>(i: I) -> ParserResult<I, ShortInt> {
168 context("parse_short_int", be_i16).parse(i)
169}
170
171pub fn parse_short_uint<I: ParsableInput>(i: I) -> ParserResult<I, ShortUInt> {
173 context("parse_short_uint", be_u16).parse(i)
174}
175
176pub fn parse_long_int<I: ParsableInput>(i: I) -> ParserResult<I, LongInt> {
178 context("parse_long_int", be_i32).parse(i)
179}
180
181pub fn parse_long_uint<I: ParsableInput>(i: I) -> ParserResult<I, LongUInt> {
183 context("parse_long_uint", be_u32).parse(i)
184}
185
186pub fn parse_long_long_int<I: ParsableInput>(i: I) -> ParserResult<I, LongLongInt> {
188 context("parse_long_long_int", be_i64).parse(i)
189}
190
191pub fn parse_long_long_uint<I: ParsableInput>(i: I) -> ParserResult<I, LongLongUInt> {
193 context("parse_long_long_uint", be_u64).parse(i)
194}
195
196pub fn parse_float<I: ParsableInput>(i: I) -> ParserResult<I, Float> {
198 context("parse_float", be_f32).parse(i)
199}
200
201pub fn parse_double<I: ParsableInput>(i: I) -> ParserResult<I, Double> {
203 context("parse_double", be_f64).parse(i)
204}
205
206pub fn parse_decimal_value<I: ParsableInput>(i: I) -> ParserResult<I, DecimalValue> {
208 context(
209 "parse_decimal_value",
210 map(
211 pair(parse_short_short_uint, parse_long_uint),
212 |(scale, value)| DecimalValue { scale, value },
213 ),
214 )
215 .parse(i)
216}
217
218fn make_str<I: Input<Item = u8>>(i: I) -> Result<String, std::string::FromUtf8Error> {
219 String::from_utf8(i.iter_elements().collect())
220}
221
222pub fn parse_short_string<I: ParsableInput>(i: I) -> ParserResult<I, ShortString> {
224 context(
225 "parse_short_string",
226 map(
227 map_res(flat_map(parse_short_short_uint, take), make_str),
228 ShortString::from,
229 ),
230 )
231 .parse(i)
232}
233
234pub fn parse_long_string<I: ParsableInput>(i: I) -> ParserResult<I, LongString> {
236 context(
237 "parse_long_string",
238 map(flat_map(parse_long_uint, take), |i: I| {
239 i.iter_elements().collect::<Vec<u8>>().into()
240 }),
241 )
242 .parse(i)
243}
244
245pub fn parse_field_array<I: ParsableInput>(i: I) -> ParserResult<I, FieldArray> {
247 context(
248 "parse_field_array",
249 map_parser(
250 flat_map(parse_long_uint, take),
251 all_consuming(fold_many0(
252 context("parse_field_array_entry", complete(parse_value)),
253 FieldArray::default,
254 |mut acc, elem| {
255 acc.push(elem);
256 acc
257 },
258 )),
259 ),
260 )
261 .parse(i)
262}
263
264pub fn parse_timestamp<I: ParsableInput>(i: I) -> ParserResult<I, Timestamp> {
266 context("parse_timestamp", parse_long_long_uint).parse(i)
267}
268
269pub fn parse_field_table<I: ParsableInput>(i: I) -> ParserResult<I, FieldTable> {
271 context(
272 "parse_field_table",
273 map_parser(
274 flat_map(parse_long_uint, take),
275 all_consuming(fold_many0(
276 context(
277 "parse_field_table_entry",
278 complete(pair(parse_short_string, parse_value)),
279 ),
280 FieldTable::default,
281 |mut acc, (key, value)| {
282 acc.insert(key, value);
283 acc
284 },
285 )),
286 ),
287 )
288 .parse(i)
289}
290
291pub fn parse_byte_array<I: ParsableInput>(i: I) -> ParserResult<I, ByteArray> {
293 context(
294 "parse_byte_array",
295 map(flat_map(parse_long_uint, take), |i: I| {
296 i.iter_elements().collect::<Vec<u8>>().into()
297 }),
298 )
299 .parse(i)
300}
301
302pub fn parse_flags<I: ParsableInput>(i: I, names: &[&str]) -> ParserResult<I, AMQPFlags> {
304 context(
305 "parse_flags",
306 map(take((names.len() + 7) / 8), |b| {
307 AMQPFlags::from_bytes(names, b)
308 }),
309 )
310 .parse(i)
311}
312
313pub mod traits {
315 pub use nom::{Compare, CompareResult, Input, Needed};
317
318 pub trait ParsableInput: Clone + Compare<&'static [u8]> + Input<Item = u8> + PartialEq {}
320
321 impl<T: Clone + Compare<&'static [u8]> + Input<Item = u8> + PartialEq> ParsableInput for T {}
322}
323
324#[cfg(test)]
325mod test {
326 use super::*;
327
328 const EMPTY: &[u8] = b"";
329
330 #[test]
331 fn test_parse_value() {
332 assert_eq!(
333 parse_value(&[84, 42, 42, 42, 42, 42, 42, 42, 42][..]),
334 Ok((EMPTY, AMQPValue::Timestamp(3038287259199220266)))
335 );
336 assert_eq!(
337 parse_value(&[83, 0, 0, 0, 4, 116, 101, 115, 116][..]),
338 Ok((EMPTY, AMQPValue::LongString("test".into())))
339 );
340 }
341
342 #[test]
343 fn test_parse_raw_value() {
344 assert_eq!(
345 parse_raw_value(AMQPType::Timestamp).parse(&[42, 42, 42, 42, 42, 42, 42, 42][..]),
346 Ok((EMPTY, AMQPValue::Timestamp(3038287259199220266)))
347 );
348 assert_eq!(
349 parse_raw_value(AMQPType::LongString).parse(&[0, 0, 0, 4, 116, 101, 115, 116][..]),
350 Ok((EMPTY, AMQPValue::LongString("test".into())))
351 );
352 assert_eq!(
354 parse_raw_value(AMQPType::LongLongUInt).parse(&[42, 42, 42, 42, 42, 42, 42, 42][..]),
355 Ok((EMPTY, AMQPValue::LongLongInt(3038287259199220266)))
356 );
357 assert_eq!(
358 parse_raw_value(AMQPType::ShortString).parse(&[4, 116, 101, 115, 116][..]),
359 Ok((EMPTY, AMQPValue::ShortString("test".into())))
360 );
361 }
362
363 #[test]
364 fn test_parse_type() {
365 assert_eq!(parse_type(&[116][..]), Ok((EMPTY, AMQPType::Boolean)));
366 assert_eq!(parse_type(&[102][..]), Ok((EMPTY, AMQPType::Float)));
367 }
368
369 #[test]
370 fn test_parse_id() {
371 assert_eq!(parse_id(&[0, 0][..]), Ok((EMPTY, 0)));
372 assert_eq!(parse_id(&[255, 255][..]), Ok((EMPTY, 65535)));
373 }
374
375 #[test]
376 fn test_parse_boolean() {
377 assert_eq!(parse_boolean(&[0][..]), Ok((EMPTY, false)));
378 assert_eq!(parse_boolean(&[1][..]), Ok((EMPTY, true)));
379 }
380
381 #[test]
382 fn test_parse_short_short_int() {
383 assert_eq!(parse_short_short_int(&[0][..]), Ok((EMPTY, 0)));
384 assert_eq!(parse_short_short_int(&[255][..]), Ok((EMPTY, -1)));
385 }
386
387 #[test]
388 fn test_parse_short_short_uint() {
389 assert_eq!(parse_short_short_uint(&[0][..]), Ok((EMPTY, 0)));
390 assert_eq!(parse_short_short_uint(&[255][..]), Ok((EMPTY, 255)));
391 }
392
393 #[test]
394 fn test_parse_short_int() {
395 assert_eq!(parse_short_int(&[0, 0][..]), Ok((EMPTY, 0)));
396 assert_eq!(parse_short_int(&[255, 255][..]), Ok((EMPTY, -1)));
397 }
398
399 #[test]
400 fn test_parse_short_uint() {
401 assert_eq!(parse_short_uint(&[0, 0][..]), Ok((EMPTY, 0)));
402 assert_eq!(parse_short_uint(&[255, 255][..]), Ok((EMPTY, 65535)));
403 }
404
405 #[test]
406 fn test_parse_long_int() {
407 assert_eq!(parse_long_int(&[0, 0, 0, 0][..]), Ok((EMPTY, 0)));
408 assert_eq!(parse_long_int(&[255, 255, 255, 255][..]), Ok((EMPTY, -1)));
409 }
410
411 #[test]
412 fn test_parse_long_uint() {
413 assert_eq!(parse_long_uint(&[0, 0, 0, 0][..]), Ok((EMPTY, 0)));
414 assert_eq!(
415 parse_long_uint(&[255, 255, 255, 255][..]),
416 Ok((EMPTY, 4294967295))
417 );
418 }
419
420 #[test]
421 fn test_parse_long_long_int() {
422 assert_eq!(
423 parse_long_long_int(&[0, 0, 0, 0, 0, 0, 0, 0][..]),
424 Ok((EMPTY, 0))
425 );
426 assert_eq!(
427 parse_long_long_int(&[255, 255, 255, 255, 255, 255, 255, 255][..]),
428 Ok((EMPTY, -1))
429 );
430 }
431
432 #[test]
433 fn test_parse_long_long_uint() {
434 assert_eq!(
435 parse_long_long_uint(&[0, 0, 0, 0, 0, 0, 0, 0][..]),
436 Ok((EMPTY, 0))
437 );
438 assert_eq!(
439 parse_long_long_uint(&[255, 255, 255, 255, 255, 255, 255, 255][..]),
440 Ok((EMPTY, 18446744073709551615))
441 );
442 }
443
444 #[test]
445 fn test_parse_float() {
446 assert_eq!(parse_float(&[0, 0, 0, 0][..]), Ok((EMPTY, 0.)));
447 assert_eq!(parse_float(&[66, 41, 174, 20][..]), Ok((EMPTY, 42.42)));
448 }
449
450 #[test]
451 fn test_parse_double() {
452 assert_eq!(parse_double(&[0, 0, 0, 0, 0, 0, 0, 0][..]), Ok((EMPTY, 0.)));
453 assert_eq!(
454 parse_double(&[64, 69, 53, 194, 143, 92, 40, 246][..]),
455 Ok((EMPTY, 42.42))
456 );
457 }
458
459 #[test]
460 fn test_parse_decimal_value() {
461 assert_eq!(
462 parse_decimal_value(&[0, 0, 0, 0, 0][..]),
463 Ok((EMPTY, DecimalValue { scale: 0, value: 0 }))
464 );
465 assert_eq!(
466 parse_decimal_value(&[255, 255, 255, 255, 255][..]),
467 Ok((
468 EMPTY,
469 DecimalValue {
470 scale: 255,
471 value: 4294967295
472 }
473 ))
474 );
475 }
476
477 #[test]
478 fn test_parse_short_string() {
479 assert_eq!(
480 parse_short_string(&[0][..]),
481 Ok((EMPTY, ShortString::default()))
482 );
483 assert_eq!(
484 parse_short_string(&[4, 116, 101, 115, 116][..]),
485 Ok((EMPTY, "test".into()))
486 );
487 }
488
489 #[test]
490 fn test_parse_long_string() {
491 assert_eq!(
492 parse_long_string(&[0, 0, 0, 0][..]),
493 Ok((EMPTY, LongString::default()))
494 );
495 assert_eq!(
496 parse_long_string(&[0, 0, 0, 4, 116, 101, 115, 116][..]),
497 Ok((EMPTY, "test".into()))
498 );
499 }
500
501 #[test]
502 fn test_parse_field_array() {
503 assert_eq!(
504 parse_field_array(&[0, 0, 0, 0][..]),
505 Ok((EMPTY, FieldArray::default()))
506 );
507 assert_eq!(
508 parse_field_array(&[0, 0, 0, 10, 83, 0, 0, 0, 4, 116, 101, 115, 116, 86][..]),
509 Ok((
510 EMPTY,
511 vec![AMQPValue::LongString("test".into()), AMQPValue::Void].into()
512 ))
513 );
514 }
515
516 #[test]
517 fn test_parse_timestamp() {
518 assert_eq!(
519 parse_timestamp(&[0, 0, 0, 0, 0, 0, 0, 0][..]),
520 Ok((EMPTY, 0))
521 );
522 assert_eq!(
523 parse_timestamp(&[255, 255, 255, 255, 255, 255, 255, 255][..]),
524 Ok((EMPTY, 18446744073709551615))
525 );
526 }
527
528 #[test]
529 fn test_parse_field_table() {
530 let mut table = FieldTable::default();
531 table.insert("test".into(), AMQPValue::LongString("test".into()));
532 table.insert("tt".into(), AMQPValue::Void);
533 assert_eq!(
534 parse_field_table(&[0, 0, 0, 0][..]),
535 Ok((EMPTY, FieldTable::default()))
536 );
537 assert_eq!(
538 parse_field_table(
539 &[
540 0, 0, 0, 18, 4, 116, 101, 115, 116, 83, 0, 0, 0, 4, 116, 101, 115, 116, 2, 116,
541 116, 86
542 ][..]
543 ),
544 Ok((EMPTY, table))
545 );
546 }
547
548 #[test]
549 fn test_parse_byte_array() {
550 assert_eq!(
551 parse_byte_array(&[0, 0, 0, 0][..]),
552 Ok((EMPTY, ByteArray::default()))
553 );
554 assert_eq!(
555 parse_byte_array(&[0, 0, 0, 4, 42, 1, 2, 3][..]),
556 Ok((EMPTY, vec![42, 1, 2, 3].into()))
557 );
558 }
559
560 #[test]
561 fn test_parse_flags() {
562 let mut flags = AMQPFlags::default();
563 let mut names = Vec::new();
564 names.push("a");
565 flags.add_flag("a".to_string(), true);
566 names.push("b");
567 flags.add_flag("b".to_string(), false);
568 names.push("c");
569 flags.add_flag("c".to_string(), true);
570 names.push("d");
571 flags.add_flag("d".to_string(), true);
572 assert_eq!(
573 parse_flags(&[0b00001101][..], &names),
574 Ok((EMPTY, flags.clone()))
575 );
576 names.push("e");
577 flags.add_flag("e".to_string(), true);
578 names.push("f");
579 flags.add_flag("f".to_string(), false);
580 names.push("g");
581 flags.add_flag("g".to_string(), true);
582 names.push("h");
583 flags.add_flag("h".to_string(), true);
584 names.push("i");
585 flags.add_flag("i".to_string(), false);
586 names.push("j");
587 flags.add_flag("j".to_string(), true);
588 assert_eq!(
589 parse_flags(&[0b11011101, 0b00000010][..], &names),
590 Ok((EMPTY, flags))
591 );
592 }
593}