@@ -120,6 +120,20 @@ pub trait StreamingIterator {
120
120
self
121
121
}
122
122
123
+ /// Consumes two iterators and returns a new iterator that iterates over both in sequence.
124
+ #[ inline]
125
+ fn chain < I > ( self , other : I ) -> Chain < Self , I >
126
+ where
127
+ Self : Sized ,
128
+ I : StreamingIterator < Item = Self :: Item > + Sized ,
129
+ {
130
+ Chain {
131
+ a : self ,
132
+ b : other,
133
+ state : ChainState :: BothForward ,
134
+ }
135
+ }
136
+
123
137
/// Produces a normal, non-streaming, iterator by cloning the elements of this iterator.
124
138
#[ inline]
125
139
fn cloned ( self ) -> Cloned < Self >
@@ -534,6 +548,86 @@ pub fn empty<I>() -> Empty<I> {
534
548
}
535
549
}
536
550
551
+ /// A streaming iterator that concatenates two streaming iterators
552
+ #[ derive( Debug ) ]
553
+ pub struct Chain < A , B > {
554
+ a : A ,
555
+ b : B ,
556
+ state : ChainState ,
557
+ }
558
+
559
+ #[ derive( Debug ) ]
560
+ enum ChainState {
561
+ // Both iterators have items remaining and we are iterating forward
562
+ BothForward ,
563
+ // Both iterators have items remaining and we are iterating backward
564
+ BothBackward ,
565
+ // Only the front iterator has items
566
+ Front ,
567
+ // Only the back iterator has items
568
+ Back ,
569
+ }
570
+
571
+ impl < A , B > StreamingIterator for Chain < A , B >
572
+ where
573
+ A : StreamingIterator ,
574
+ B : StreamingIterator < Item = A :: Item > ,
575
+ {
576
+ type Item = A :: Item ;
577
+
578
+ #[ inline]
579
+ fn advance ( & mut self ) {
580
+ use ChainState :: * ;
581
+
582
+ match self . state {
583
+ BothForward | BothBackward => {
584
+ self . state = if self . a . next ( ) . is_none ( ) {
585
+ self . b . advance ( ) ;
586
+ Back
587
+ } else {
588
+ BothForward
589
+ } ;
590
+ }
591
+ Front => self . a . advance ( ) ,
592
+ Back => self . b . advance ( ) ,
593
+ }
594
+ }
595
+
596
+ #[ inline]
597
+ fn get ( & self ) -> Option < & Self :: Item > {
598
+ use ChainState :: * ;
599
+
600
+ match self . state {
601
+ BothForward | Front => self . a . get ( ) ,
602
+ BothBackward | Back => self . b . get ( ) ,
603
+ }
604
+ }
605
+ }
606
+
607
+ impl < A , B > DoubleEndedStreamingIterator for Chain < A , B >
608
+ where
609
+ A : DoubleEndedStreamingIterator ,
610
+ B : DoubleEndedStreamingIterator < Item = A :: Item > ,
611
+ {
612
+ #[ inline]
613
+ fn advance_back ( & mut self ) {
614
+ use ChainState :: * ;
615
+
616
+ match self . state {
617
+ BothForward | BothBackward => {
618
+ self . state = if self . b . next_back ( ) . is_none ( ) {
619
+ self . a . advance_back ( ) ;
620
+ Front
621
+ } else {
622
+ BothBackward
623
+ } ;
624
+ }
625
+ Front => self . a . advance_back ( ) ,
626
+ Back => self . b . advance_back ( ) ,
627
+ }
628
+ }
629
+ }
630
+
537
631
/// A normal, non-streaming, iterator which converts the elements of a streaming iterator into owned
538
632
/// values by cloning them.
539
633
#[ derive( Clone , Debug ) ]
@@ -1502,6 +1596,21 @@ mod test {
1502
1596
assert_eq ! ( it. get( ) , None ) ;
1503
1597
}
1504
1598
1599
+ fn test_back < I > ( mut it : I , expected : & [ I :: Item ] )
1600
+ where
1601
+ I : DoubleEndedStreamingIterator ,
1602
+ I :: Item : Sized + PartialEq + Debug ,
1603
+ {
1604
+ for item in expected {
1605
+ it. advance_back ( ) ;
1606
+ assert_eq ! ( it. get( ) , Some ( item) ) ;
1607
+ assert_eq ! ( it. get( ) , Some ( item) ) ;
1608
+ }
1609
+ it. advance_back ( ) ;
1610
+ assert_eq ! ( it. get( ) , None ) ;
1611
+ assert_eq ! ( it. get( ) , None ) ;
1612
+ }
1613
+
1505
1614
#[ test]
1506
1615
fn all ( ) {
1507
1616
let items = [ 0 , 1 , 2 ] ;
@@ -1518,6 +1627,50 @@ mod test {
1518
1627
assert ! ( !it. clone( ) . any( |& i| i > 2 ) ) ;
1519
1628
}
1520
1629
1630
+ #[ test]
1631
+ fn test_chain ( ) {
1632
+ let items_a = [ 0 , 1 , 2 , 3 ] ;
1633
+ let items_b = [ 10 , 20 , 30 ] ;
1634
+ let expected = [ 0 , 1 , 2 , 3 , 10 , 20 , 30 ] ;
1635
+
1636
+ let it = convert ( items_a. iter ( ) . cloned ( ) ) . chain ( convert ( items_b. iter ( ) . cloned ( ) ) ) ;
1637
+ test ( it, & expected) ;
1638
+ }
1639
+
1640
+ #[ test]
1641
+ fn test_chain_back ( ) {
1642
+ let items_a = [ 0 , 1 , 2 , 3 ] ;
1643
+ let items_b = [ 10 , 20 , 30 ] ;
1644
+ let expected = [ 30 , 20 , 10 , 3 , 2 , 1 , 0 ] ;
1645
+
1646
+ let it = convert ( items_a. iter ( ) . cloned ( ) ) . chain ( convert ( items_b. iter ( ) . cloned ( ) ) ) ;
1647
+ test_back ( it, & expected) ;
1648
+ }
1649
+
1650
+ #[ test]
1651
+ fn test_chain_mixed ( ) {
1652
+ let items_a = [ 0 , 1 , 2 , 3 ] ;
1653
+ let items_b = [ 10 , 20 , 30 ] ;
1654
+
1655
+ let mut it = convert ( items_a. iter ( ) . cloned ( ) ) . chain ( convert ( items_b. iter ( ) . cloned ( ) ) ) ;
1656
+
1657
+ assert_eq ! ( it. get( ) , None ) ;
1658
+ it. advance ( ) ;
1659
+ assert_eq ! ( it. get( ) . cloned( ) , Some ( 0 ) ) ;
1660
+ it. advance_back ( ) ;
1661
+ assert_eq ! ( it. get( ) . cloned( ) , Some ( 30 ) ) ;
1662
+ it. advance ( ) ;
1663
+ assert_eq ! ( it. get( ) . cloned( ) , Some ( 1 ) ) ;
1664
+ it. advance_back ( ) ;
1665
+ assert_eq ! ( it. get( ) . cloned( ) , Some ( 20 ) ) ;
1666
+ it. advance ( ) ;
1667
+ assert_eq ! ( it. get( ) . cloned( ) , Some ( 2 ) ) ;
1668
+ it. advance_back ( ) ;
1669
+ assert_eq ! ( it. get( ) . cloned( ) , Some ( 10 ) ) ;
1670
+ it. advance_back ( ) ;
1671
+ assert_eq ! ( it. get( ) . cloned( ) , Some ( 3 ) ) ;
1672
+ }
1673
+
1521
1674
#[ test]
1522
1675
fn cloned ( ) {
1523
1676
let items = [ 0 , 1 ] ;
0 commit comments