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