@@ -667,6 +667,158 @@ impl dyn Error {
667
667
Err ( self )
668
668
}
669
669
}
670
+
671
+ /// Returns an iterator starting with the current error and continuing with
672
+ /// recursively calling [`source`].
673
+ ///
674
+ /// # Examples
675
+ ///
676
+ /// ```
677
+ /// #![feature(error_iter)]
678
+ /// use std::error::Error;
679
+ /// use std::fmt;
680
+ ///
681
+ /// #[derive(Debug)]
682
+ /// struct A;
683
+ ///
684
+ /// #[derive(Debug)]
685
+ /// struct B(Option<Box<dyn Error + 'static>>);
686
+ ///
687
+ /// impl fmt::Display for A {
688
+ /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
689
+ /// write!(f, "A")
690
+ /// }
691
+ /// }
692
+ ///
693
+ /// impl fmt::Display for B {
694
+ /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
695
+ /// write!(f, "B")
696
+ /// }
697
+ /// }
698
+ ///
699
+ /// impl Error for A {}
700
+ ///
701
+ /// impl Error for B {
702
+ /// fn source(&self) -> Option<&(dyn Error + 'static)> {
703
+ /// self.0.as_ref().map(|e| e.as_ref())
704
+ /// }
705
+ /// }
706
+ ///
707
+ /// let b = B(Some(Box::new(A)));
708
+ ///
709
+ /// // let err : Box<Error> = b.into(); // or
710
+ /// let err = &b as &(dyn Error);
711
+ ///
712
+ /// let mut iter = err.iter_chain();
713
+ ///
714
+ /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
715
+ /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
716
+ /// assert!(iter.next().is_none());
717
+ /// assert!(iter.next().is_none());
718
+ /// ```
719
+ ///
720
+ /// [`source`]: trait.Error.html#method.source
721
+ #[ unstable( feature = "error_iter" , issue = "58289" ) ]
722
+ #[ inline]
723
+ pub fn iter_chain ( & self ) -> ErrorIter {
724
+ ErrorIter {
725
+ current : Some ( self ) ,
726
+ }
727
+ }
728
+
729
+ /// Returns an iterator starting with the [`source`] of this error
730
+ /// and continuing with recursively calling [`source`].
731
+ ///
732
+ /// # Examples
733
+ ///
734
+ /// ```
735
+ /// #![feature(error_iter)]
736
+ /// use std::error::Error;
737
+ /// use std::fmt;
738
+ ///
739
+ /// #[derive(Debug)]
740
+ /// struct A;
741
+ ///
742
+ /// #[derive(Debug)]
743
+ /// struct B(Option<Box<dyn Error + 'static>>);
744
+ ///
745
+ /// #[derive(Debug)]
746
+ /// struct C(Option<Box<dyn Error + 'static>>);
747
+ ///
748
+ /// impl fmt::Display for A {
749
+ /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
750
+ /// write!(f, "A")
751
+ /// }
752
+ /// }
753
+ ///
754
+ /// impl fmt::Display for B {
755
+ /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
756
+ /// write!(f, "B")
757
+ /// }
758
+ /// }
759
+ ///
760
+ /// impl fmt::Display for C {
761
+ /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
762
+ /// write!(f, "C")
763
+ /// }
764
+ /// }
765
+ ///
766
+ /// impl Error for A {}
767
+ ///
768
+ /// impl Error for B {
769
+ /// fn source(&self) -> Option<&(dyn Error + 'static)> {
770
+ /// self.0.as_ref().map(|e| e.as_ref())
771
+ /// }
772
+ /// }
773
+ ///
774
+ /// impl Error for C {
775
+ /// fn source(&self) -> Option<&(dyn Error + 'static)> {
776
+ /// self.0.as_ref().map(|e| e.as_ref())
777
+ /// }
778
+ /// }
779
+ ///
780
+ /// let b = B(Some(Box::new(A)));
781
+ /// let c = C(Some(Box::new(b)));
782
+ ///
783
+ /// // let err : Box<Error> = c.into(); // or
784
+ /// let err = &c as &(dyn Error);
785
+ ///
786
+ /// let mut iter = err.iter_sources();
787
+ ///
788
+ /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
789
+ /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
790
+ /// assert!(iter.next().is_none());
791
+ /// assert!(iter.next().is_none());
792
+ /// ```
793
+ ///
794
+ /// [`source`]: trait.Error.html#method.source
795
+ #[ inline]
796
+ #[ unstable( feature = "error_iter" , issue = "58289" ) ]
797
+ pub fn iter_sources ( & self ) -> ErrorIter {
798
+ ErrorIter {
799
+ current : self . source ( ) ,
800
+ }
801
+ }
802
+ }
803
+
804
+ /// An iterator over [`Error`]
805
+ ///
806
+ /// [`Error`]: trait.Error.html
807
+ #[ unstable( feature = "error_iter" , issue = "58289" ) ]
808
+ #[ derive( Copy , Clone , Debug ) ]
809
+ pub struct ErrorIter < ' a > {
810
+ current : Option < & ' a ( dyn Error + ' static ) > ,
811
+ }
812
+
813
+ #[ unstable( feature = "error_iter" , issue = "58289" ) ]
814
+ impl < ' a > Iterator for ErrorIter < ' a > {
815
+ type Item = & ' a ( dyn Error + ' static ) ;
816
+
817
+ fn next ( & mut self ) -> Option < Self :: Item > {
818
+ let current = self . current ;
819
+ self . current = self . current . and_then ( Error :: source) ;
820
+ current
821
+ }
670
822
}
671
823
672
824
impl dyn Error + Send {
0 commit comments