1#![allow(
188 clippy::inline_always,
189 clippy::type_complexity,
190 clippy::too_many_arguments,
191 clippy::match_like_matches_macro
192)]
193#![cfg_attr(not(feature = "std"), no_std)]
194#![cfg_attr(docsrs, feature(doc_cfg))]
195
196#[cfg(feature = "alloc")]
197extern crate alloc;
198
199#[doc(inline)]
200pub use crate::error::{ParseError, ParseResult, StdParseResult};
201
202#[cfg(feature = "std")]
203#[doc(inline)]
204pub use crate::parser::EasyParser;
205
206#[doc(inline)]
207pub use crate::parser::Parser;
208
209#[doc(inline)]
210pub use crate::stream::{Positioned, RangeStream, RangeStreamOnce, Stream, StreamOnce};
211
212#[doc(inline)]
213pub use crate::parser::{
214 choice::optional,
215 combinator::{attempt, look_ahead, not_followed_by},
216 error::{unexpected, unexpected_any},
217 function::parser,
218 repeat::{
219 chainl1, chainr1, count, count_min_max, many, many1, sep_by, sep_by1, sep_end_by,
220 sep_end_by1, skip_count, skip_count_min_max, skip_many, skip_many1,
221 },
222 sequence::between,
223 token::{
224 any, eof, none_of, one_of, position, produce, satisfy, satisfy_map, token, tokens, value,
225 },
226};
227
228#[doc(inline)]
229pub use crate::parser::choice::choice;
230
231#[doc(inline)]
232pub use crate::parser::combinator::from_str;
233
234#[doc(inline)]
235pub use crate::parser::token::tokens_cmp;
236
237#[macro_export]
322macro_rules! parser {
323 (
324 type PartialState = $partial_state: ty;
325 $(#[$attr:meta])*
326 $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),*)
327 ($input_type: ty) -> $output_type: ty
328 where [$($where_clause: tt)*]
329 $parser: block
330 ) => {
331 $crate::combine_parser_impl!{
332 #[allow(non_camel_case_types)]
333 #[doc(hidden)]
334 $fn_vis struct $name;
335 (type PartialState = ($partial_state);)
336 $(#[$attr])*
337 $fn_vis fn $name [$($type_params)*]($($arg : $arg_type),*)($input_type) -> $output_type
338 where [$($where_clause)*]
339 $parser
340 }
341 };
342 (
343 $(#[$derive:meta])*
344 $struct_vis: vis struct $type_name: ident;
345 type PartialState = $partial_state: ty;
346 $(#[$attr:meta])*
347 $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),* )
348 ($input_type: ty) -> $output_type: ty
349 where [$($where_clause: tt)*]
350 $parser: block
351 ) => {
352 $crate::combine_parser_impl!{
353 $(#[$derive])*
354 $struct_vis struct $type_name;
355 (type PartialState = ($partial_state);)
356 $(#[$attr])*
357 $fn_vis fn $name [$($type_params)*]($($arg : $arg_type),*)($input_type) -> $output_type
358 where [$($where_clause)*]
359 $parser
360 }
361 };
362 (
363 $(#[$attr:meta])*
364 $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),*)
365 ($input_type: ty) -> $output_type: ty
366 where [$($where_clause: tt)*]
367 $parser: block
368 ) => {
369 $crate::combine_parser_impl!{
370 #[allow(non_camel_case_types)]
371 #[doc(hidden)]
372 $fn_vis struct $name;
373 (type PartialState = (());)
374 $(#[$attr])*
375 $fn_vis fn $name [$($type_params)*]($($arg : $arg_type),*)($input_type) -> $output_type
376 where [$($where_clause)*]
377 $parser
378 }
379 };
380 (
381 $(#[$derive:meta])*
382 $struct_vis: vis struct $type_name: ident;
383 $(#[$attr:meta])*
384 $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),* )
385 ($input_type: ty) -> $output_type: ty
386 where [$($where_clause: tt)*]
387 $parser: block
388 ) => {
389 $crate::combine_parser_impl!{
390 $(#[$derive])*
391 $struct_vis struct $type_name;
392 (type PartialState = (());)
393 $(#[$attr])*
394 $fn_vis fn $name [$($type_params)*]($($arg : $arg_type),*)($input_type) -> $output_type
395 where [$($where_clause)*]
396 $parser
397 }
398 };
399}
400
401#[doc(hidden)]
402#[macro_export]
403macro_rules! combine_parse_partial {
404 ((()) $mode:ident $input:ident $state:ident $parser:block) => {{
405 let _ = $state;
406 let mut state = Default::default();
407 let state = &mut state;
408 $parser.parse_mode($mode, $input, state)
409 }};
410 (($ignored:ty) $mode:ident $input:ident $state:ident $parser:block) => {
411 $parser.parse_mode($mode, $input, $state)
412 };
413}
414
415#[doc(hidden)]
416#[macro_export]
417macro_rules! combine_parser_impl {
418 (
419 $(#[$derive:meta])*
420 $struct_vis: vis struct $type_name: ident;
421 (type PartialState = ($($partial_state: tt)*);)
422 $(#[$attr:meta])*
423 $fn_vis: vis fn $name: ident [$($type_params: tt)*]( $($arg: ident : $arg_type: ty),*)
424 ($input_type: ty) -> $output_type: ty
425 where [$($where_clause: tt)*]
426 $parser: block
427 ) => {
428
429 $(#[$derive])*
430 $struct_vis struct $type_name<$($type_params)*>
431 where <$input_type as $crate::stream::StreamOnce>::Error:
432 $crate::error::ParseError<
433 <$input_type as $crate::stream::StreamOnce>::Token,
434 <$input_type as $crate::stream::StreamOnce>::Range,
435 <$input_type as $crate::stream::StreamOnce>::Position
436 >,
437 $input_type: $crate::stream::Stream,
438 $($where_clause)*
439 {
440 $(pub $arg : $arg_type,)*
441 __marker: $crate::lib::marker::PhantomData<fn ($input_type) -> $output_type>
442 }
443
444 #[allow(non_shorthand_field_patterns)]
446 impl<$($type_params)*> $crate::Parser<$input_type> for $type_name<$($type_params)*>
447 where <$input_type as $crate::stream::StreamOnce>::Error:
448 $crate::error::ParseError<
449 <$input_type as $crate::stream::StreamOnce>::Token,
450 <$input_type as $crate::stream::StreamOnce>::Range,
451 <$input_type as $crate::stream::StreamOnce>::Position
452 >,
453 $input_type: $crate::stream::Stream,
454 $($where_clause)*
455 {
456
457 type Output = $output_type;
458 type PartialState = $($partial_state)*;
459
460 $crate::parse_mode!($input_type);
461 #[inline]
462 fn parse_mode_impl<M>(
463 &mut self,
464 mode: M,
465 input: &mut $input_type,
466 state: &mut Self::PartialState,
467 ) -> $crate::error::ParseResult<$output_type, <$input_type as $crate::stream::StreamOnce>::Error>
468 where M: $crate::parser::ParseMode
469 {
470 let $type_name { $( $arg: ref mut $arg,)* .. } = *self;
471 $crate::combine_parse_partial!(($($partial_state)*) mode input state $parser)
472 }
473
474 #[inline]
475 fn add_error(
476 &mut self,
477 errors: &mut $crate::error::Tracked<
478 <$input_type as $crate::stream::StreamOnce>::Error
479 >)
480 {
481 let $type_name { $( $arg : ref mut $arg,)* .. } = *self;
482 let mut parser = $parser;
483 {
484 let _: &mut dyn $crate::Parser< $input_type, Output = $output_type, PartialState = _> = &mut parser;
485 }
486 parser.add_error(errors)
487 }
488
489 fn add_committed_expected_error(
490 &mut self,
491 errors: &mut $crate::error::Tracked<
492 <$input_type as $crate::stream::StreamOnce>::Error
493 >)
494 {
495 let $type_name { $( $arg : ref mut $arg,)* .. } = *self;
496 let mut parser = $parser;
497 {
498 let _: &mut dyn $crate::Parser< $input_type, Output = $output_type, PartialState = _> = &mut parser;
499 }
500 parser.add_committed_expected_error(errors)
501 }
502 }
503
504 $(#[$attr])*
505 #[inline]
506 $fn_vis fn $name< $($type_params)* >(
507 $($arg : $arg_type),*
508 ) -> $type_name<$($type_params)*>
509 where <$input_type as $crate::stream::StreamOnce>::Error:
510 $crate::error::ParseError<
511 <$input_type as $crate::stream::StreamOnce>::Token,
512 <$input_type as $crate::stream::StreamOnce>::Range,
513 <$input_type as $crate::stream::StreamOnce>::Position
514 >,
515 $input_type: $crate::stream::Stream,
516 $($where_clause)*
517 {
518 $type_name {
519 $($arg,)*
520 __marker: $crate::lib::marker::PhantomData
521 }
522 }
523 };
524}
525
526macro_rules! forward_parser {
528 ($input: ty, $method: ident $( $methods: ident)*, $($field: tt)*) => {
529 forward_parser!($input, $method $($field)+);
530 forward_parser!($input, $($methods)*, $($field)+);
531 };
532 ($input: ty, parse_mode $($field: tt)+) => {
533 #[inline]
534 fn parse_mode_impl<M>(
535 &mut self,
536 mode: M,
537 input: &mut $input,
538 state: &mut Self::PartialState,
539 ) -> ParseResult<Self::Output, <$input as $crate::StreamOnce>::Error>
540 where
541 M: ParseMode,
542 {
543 self.$($field)+.parse_mode(mode, input, state).map(|(a, _)| a)
544 }
545 };
546 ($input: ty, parse_lazy $($field: tt)+) => {
547 fn parse_lazy(
548 &mut self,
549 input: &mut $input,
550 ) -> ParseResult<Self::Output, <$input as $crate::StreamOnce>::Error> {
551 self.$($field)+.parse_lazy(input)
552 }
553 };
554 ($input: ty, parse_first $($field: tt)+) => {
555 fn parse_first(
556 &mut self,
557 input: &mut $input,
558 state: &mut Self::PartialState,
559 ) -> ParseResult<Self::Output, <$input as $crate::StreamOnce>::Error> {
560 self.$($field)+.parse_first(input, state)
561 }
562 };
563 ($input: ty, parse_partial $($field: tt)+) => {
564 fn parse_partial(
565 &mut self,
566 input: &mut $input,
567 state: &mut Self::PartialState,
568 ) -> ParseResult<Self::Output, <$input as $crate::StreamOnce>::Error> {
569 self.$($field)+.parse_partial(input, state)
570 }
571 };
572 ($input: ty, add_error $($field: tt)+) => {
573
574 fn add_error(&mut self, error: &mut $crate::error::Tracked<<$input as $crate::StreamOnce>::Error>) {
575 self.$($field)+.add_error(error)
576 }
577 };
578 ($input: ty, add_committed_expected_error $($field: tt)+) => {
579 fn add_committed_expected_error(&mut self, error: &mut $crate::error::Tracked<<$input as $crate::StreamOnce>::Error>) {
580 self.$($field)+.add_committed_expected_error(error)
581 }
582 };
583 ($input: ty, parser_count $($field: tt)+) => {
584 fn parser_count(&self) -> $crate::ErrorOffset {
585 self.$($field)+.parser_count()
586 }
587 };
588 ($input: ty, $field: tt) => {
589 forward_parser!($input, parse_lazy parse_first parse_partial add_error add_committed_expected_error parser_count, $field);
590 };
591 ($input: ty, $($field: tt)+) => {
592 };
593}
594
595#[doc(hidden)]
598pub mod lib {
599 #[cfg(not(feature = "std"))]
600 pub use core::*;
601
602 #[cfg(feature = "std")]
603 pub use std::*;
604}
605
606#[cfg(feature = "std")]
607#[doc(inline)]
608pub use crate::stream::easy;
609
610#[macro_use]
612pub mod error;
613#[macro_use]
614pub mod stream;
615#[macro_use]
616pub mod parser;
617
618#[cfg(feature = "futures-core-03")]
619pub mod future_ext;
620
621#[doc(hidden)]
622#[derive(Clone, PartialOrd, PartialEq, Debug, Copy)]
623pub struct ErrorOffset(u8);
624
625#[cfg(test)]
626mod tests {
627
628 use crate::parser::char::{char, string};
629
630 use super::*;
631
632 #[test]
633 fn chainl1_error_consume() {
634 fn first<T, U>(t: T, _: U) -> T {
635 t
636 }
637 let mut p = chainl1(string("abc"), char(',').map(|_| first));
638 assert!(p.parse("abc,ab").is_err());
639 }
640
641 #[test]
642 fn choice_strings() {
643 let mut fruits = [
644 attempt(string("Apple")),
645 attempt(string("Banana")),
646 attempt(string("Cherry")),
647 attempt(string("Date")),
648 attempt(string("Fig")),
649 attempt(string("Grape")),
650 ];
651 let mut parser = choice(&mut fruits);
652 assert_eq!(parser.parse("Apple"), Ok(("Apple", "")));
653 assert_eq!(parser.parse("Banana"), Ok(("Banana", "")));
654 assert_eq!(parser.parse("Cherry"), Ok(("Cherry", "")));
655 assert_eq!(parser.parse("DateABC"), Ok(("Date", "ABC")));
656 assert_eq!(parser.parse("Fig123"), Ok(("Fig", "123")));
657 assert_eq!(parser.parse("GrapeApple"), Ok(("Grape", "Apple")));
658 }
659}
660
661#[cfg(all(feature = "std", test))]
662mod std_tests {
663
664 use crate::{
665 error::StdParseResult,
666 parser::char::{alpha_num, char, digit, letter, spaces, string},
667 stream::{
668 easy,
669 position::{self, SourcePosition},
670 },
671 };
672
673 use super::{easy::Error, error::Commit, stream::IteratorStream, *};
674
675 #[test]
676 fn optional_error_consume() {
677 let mut p = optional(string("abc"));
678 let err = p.easy_parse(position::Stream::new("ab")).unwrap_err();
679 assert_eq!(err.position, SourcePosition { line: 1, column: 1 });
680 }
681
682 fn follow<Input>(input: &mut Input) -> StdParseResult<(), Input>
683 where
684 Input: Stream<Token = char, Error = easy::ParseError<Input>>,
685 Input::Position: Default,
686 Input::Error: std::fmt::Debug,
687 Input::Token: PartialEq,
688 Input::Range: PartialEq,
689 {
690 let before = input.checkpoint();
691 match input.uncons() {
692 Ok(c) => {
693 if c.is_alphanumeric() {
694 input.reset(before).unwrap();
695 let e = Error::Unexpected(c.into());
696 Err(Commit::Peek(easy::Errors::new(input.position(), e).into()))
697 } else {
698 Ok(((), Commit::Peek(())))
699 }
700 }
701 Err(_) => Ok(((), Commit::Peek(()))),
702 }
703 }
704
705 fn integer<Input>(input: &mut Input) -> StdParseResult<i64, Input>
706 where
707 Input: Stream<Token = char>,
708 {
709 let (s, input) = many1::<String, _, _>(digit())
710 .expected("integer")
711 .parse_stream(input)
712 .into_result()?;
713 let mut n = 0;
714 for c in s.chars() {
715 n = n * 10 + (c as i64 - '0' as i64);
716 }
717 Ok((n, input))
718 }
719
720 #[test]
721 fn test_integer() {
722 let result = parser(integer).parse("123");
723 assert_eq!(result, Ok((123i64, "")));
724 }
725 #[test]
726 fn list() {
727 let mut p = sep_by(parser(integer), char(','));
728 let result = p.parse("123,4,56");
729 assert_eq!(result, Ok((vec![123i64, 4, 56], "")));
730 }
731
732 #[test]
733 fn iterator() {
734 let result = parser(integer)
735 .parse(position::Stream::new(IteratorStream::new("123".chars())))
736 .map(|(i, mut input)| (i, input.uncons().is_err()));
737 assert_eq!(result, Ok((123i64, true)));
738 }
739
740 #[test]
741 fn field() {
742 let word = || many(alpha_num());
743 let c_decl = (word(), spaces(), char(':'), spaces(), word())
744 .map(|t| (t.0, t.4))
745 .parse("x: int");
746 assert_eq!(c_decl, Ok((("x".to_string(), "int".to_string()), "")));
747 }
748
749 #[test]
750 fn source_position() {
751 let source = r"
752123
753";
754 let mut parsed_state = position::Stream::with_positioner(source, SourcePosition::new());
755 let result = (spaces(), parser(integer), spaces())
756 .map(|t| t.1)
757 .parse_stream(&mut parsed_state)
758 .into_result();
759 let state = Commit::Commit(position::Stream {
760 positioner: SourcePosition { line: 3, column: 1 },
761 input: "",
762 });
763 assert_eq!(
764 result.map(|(x, c)| (x, c.map(|_| parsed_state))),
765 Ok((123i64, state))
766 );
767 }
768
769 #[derive(Debug, PartialEq)]
770 pub enum Expr {
771 Id(String),
772 Int(i64),
773 Array(Vec<Expr>),
774 Plus(Box<Expr>, Box<Expr>),
775 Times(Box<Expr>, Box<Expr>),
776 }
777
778 parser! {
779 fn expr[Input]()(Input) -> Expr
780 where
781 [Input: Stream<Token = char>,]
782 {
783 let word = many1(letter()).expected("identifier");
784 let integer = parser(integer);
785 let array = between(char('['), char(']'), sep_by(expr(), char(','))).expected("[");
786 let paren_expr = between(char('('), char(')'), parser(term)).expected("(");
787 spaces()
788 .silent()
789 .with(
790 word.map(Expr::Id)
791 .or(integer.map(Expr::Int))
792 .or(array.map(Expr::Array))
793 .or(paren_expr),
794 )
795 .skip(spaces().silent())
796 }
797 }
798
799 #[test]
800 fn expression_basic() {
801 let result = sep_by(expr(), char(',')).parse("int, 100, [[], 123]");
802 let exprs = vec![
803 Expr::Id("int".to_string()),
804 Expr::Int(100),
805 Expr::Array(vec![Expr::Array(vec![]), Expr::Int(123)]),
806 ];
807 assert_eq!(result, Ok((exprs, "")));
808 }
809
810 #[test]
811 fn expression_error() {
812 let input = r"
813,123
814";
815 let result = expr().easy_parse(position::Stream::new(input));
816 let err = easy::Errors {
817 position: SourcePosition { line: 2, column: 1 },
818 errors: vec![
819 Error::Unexpected(','.into()),
820 Error::Expected("integer".into()),
821 Error::Expected("identifier".into()),
822 Error::Expected("[".into()),
823 Error::Expected("(".into()),
824 ],
825 };
826 assert_eq!(result, Err(err));
827 }
828
829 fn term<Input>(input: &mut Input) -> StdParseResult<Expr, Input>
830 where
831 Input: Stream<Token = char>,
832 {
833 fn times(l: Expr, r: Expr) -> Expr {
834 Expr::Times(Box::new(l), Box::new(r))
835 }
836 fn plus(l: Expr, r: Expr) -> Expr {
837 Expr::Plus(Box::new(l), Box::new(r))
838 }
839 let mul = char('*').map(|_| times);
840 let add = char('+').map(|_| plus);
841 let factor = chainl1(expr(), mul);
842 chainl1(factor, add).parse_stream(input).into()
843 }
844
845 #[test]
846 fn operators() {
847 let input = r"
8481 * 2 + 3 * test
849";
850 let (result, _) = parser(term).parse(position::Stream::new(input)).unwrap();
851
852 let e1 = Expr::Times(Box::new(Expr::Int(1)), Box::new(Expr::Int(2)));
853 let e2 = Expr::Times(
854 Box::new(Expr::Int(3)),
855 Box::new(Expr::Id("test".to_string())),
856 );
857 assert_eq!(result, Expr::Plus(Box::new(e1), Box::new(e2)));
858 }
859
860 #[test]
861 fn error_position() {
862 let mut p = string("let")
863 .skip(parser(follow))
864 .map(|x| x.to_string())
865 .or(many1(digit()));
866 match p.easy_parse(position::Stream::new("le123")) {
867 Ok(_) => panic!(),
868 Err(err) => assert_eq!(err.position, SourcePosition { line: 1, column: 1 }),
869 }
870 match p.easy_parse(position::Stream::new("let1")) {
871 Ok(_) => panic!(),
872 Err(err) => assert_eq!(err.position, SourcePosition { line: 1, column: 4 }),
873 }
874 }
875
876 #[test]
877 fn sep_by_error_consume() {
878 let mut p = sep_by::<Vec<_>, _, _, _>(string("abc"), char(','));
879 let err = p.easy_parse(position::Stream::new("ab,abc")).unwrap_err();
880 assert_eq!(err.position, SourcePosition { line: 1, column: 1 });
881 }
882
883 #[test]
884 fn inner_error_consume() {
885 let mut p = many::<Vec<_>, _, _>(between(char('['), char(']'), digit()));
886 let result = p.easy_parse(position::Stream::new("[1][2][]"));
887 assert!(result.is_err(), "{:?}", result);
888 let error = result.map(|x| format!("{:?}", x)).unwrap_err();
889 assert_eq!(error.position, SourcePosition { line: 1, column: 8 });
890 }
891
892 #[test]
893 fn infinite_recursion_in_box_parser() {
894 let _: Result<(Vec<_>, _), _> = (many(Box::new(digit()))).parse("1");
895 }
896
897 #[test]
898 fn unsized_parser() {
899 let mut parser: Box<dyn Parser<_, Output = char, PartialState = _>> = Box::new(digit());
900 let borrow_parser = &mut *parser;
901 assert_eq!(borrow_parser.parse("1"), Ok(('1', "")));
902 }
903
904 #[test]
905 fn std_error() {
906 use std::error::Error as StdError;
907
908 use std::fmt;
909
910 #[derive(Debug)]
911 struct Error;
912 impl fmt::Display for Error {
913 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
914 write!(f, "error")
915 }
916 }
917 impl StdError for Error {
918 fn description(&self) -> &str {
919 "error"
920 }
921 }
922 let result: Result<((), _), easy::Errors<char, &str, _>> =
923 EasyParser::easy_parse(&mut string("abc").and_then(|_| Err(Error)), "abc");
924 assert!(result.is_err());
925 let _ = result.map_err(|err| {
927 let err: Box<dyn StdError> = Box::new(err);
928 err
929 });
930 }
931
932 #[test]
933 fn extract_std_error() {
934 use std::error::Error as StdError;
942
943 use std::fmt;
944
945 #[derive(Clone, PartialEq, Debug)]
946 struct CloneOnly(String);
947
948 #[derive(Debug)]
949 struct DisplayVec<T>(Vec<T>);
950
951 #[derive(Debug)]
952 struct ExtractedError(usize, DisplayVec<Error<CloneOnly, DisplayVec<CloneOnly>>>);
953
954 impl StdError for ExtractedError {
955 fn description(&self) -> &str {
956 "extracted error"
957 }
958 }
959
960 impl fmt::Display for CloneOnly {
961 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
962 write!(f, "{}", self.0)
963 }
964 }
965
966 impl<T: fmt::Debug> fmt::Display for DisplayVec<T> {
967 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
968 write!(f, "[{:?}]", self.0)
969 }
970 }
971
972 impl fmt::Display for ExtractedError {
973 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
974 writeln!(f, "Parse error at {}", self.0)?;
975 Error::fmt_errors(&(self.1).0, f)
976 }
977 }
978
979 let input = &[CloneOnly("x".to_string()), CloneOnly("y".to_string())][..];
980 let result = token(CloneOnly("z".to_string()))
981 .easy_parse(input)
982 .map_err(|e| e.map_position(|p| p.translate_position(input)))
983 .map_err(|e| {
984 ExtractedError(
985 e.position,
986 DisplayVec(
987 e.errors
988 .into_iter()
989 .map(|e| e.map_range(|r| DisplayVec(r.to_owned())))
990 .collect(),
991 ),
992 )
993 });
994
995 assert!(result.is_err());
996 let _ = result.map_err(|err| {
999 let s = format!("{}", err);
1000 assert!(s.starts_with("Parse error at 0"));
1001 assert!(s.contains("Expected"));
1002 let err: Box<dyn StdError> = Box::new(err);
1003 err
1004 });
1005 }
1006}