@@ -45,49 +45,48 @@ where
4545/// The first component of the value yielded by `WithPosition`.
4646/// Indicates the position of this element in the iterator results.
4747///
48- /// When handling the first or last position,
49- /// remember to consider the special case of [`Position::Only`].
50- ///
5148/// See [`.with_position()`](crate::Itertools::with_position) for more information.
5249#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
53- pub enum Position {
54- /// This is the first element, and there is more than one element.
55- First ,
56- /// This is neither the first nor the last element.
57- Middle ,
58- /// This is the last element, and there was more than one element.
59- Last ,
60- /// This is the only element.
61- Only ,
50+ pub struct Position {
51+ /// This is the initial element (also true if there's exactly one element)
52+ pub is_first : bool ,
53+ /// This is the final element (also true if there's exactly one element)
54+ pub is_last : bool ,
55+ }
56+
57+ impl Position {
58+ /// This is the first and the last element at the same time, and there are no more elements
59+ pub fn is_exactly_one ( self ) -> bool {
60+ self . is_first && self . is_last
61+ }
62+
63+ /// This is neither first nor last element, and there will be more elements
64+ pub fn is_middle ( self ) -> bool {
65+ !self . is_first && !self . is_last
66+ }
67+
68+ /// This is the initial element (also true if there's exactly one element)
69+ pub fn is_first ( self ) -> bool {
70+ self . is_first
71+ }
72+
73+ /// This is the final element (also true if there's exactly one element)
74+ pub fn is_last ( self ) -> bool {
75+ self . is_last
76+ }
6277}
6378
6479impl < I : Iterator > Iterator for WithPosition < I > {
6580 type Item = ( Position , I :: Item ) ;
6681
6782 fn next ( & mut self ) -> Option < Self :: Item > {
68- match self . peekable . next ( ) {
69- Some ( item) => {
70- if !self . handled_first {
71- // Haven't seen the first item yet, and there is one to give.
72- self . handled_first = true ;
73- // Peek to see if this is also the last item,
74- // in which case tag it as `Only`.
75- match self . peekable . peek ( ) {
76- Some ( _) => Some ( ( Position :: First , item) ) ,
77- None => Some ( ( Position :: Only , item) ) ,
78- }
79- } else {
80- // Have seen the first item, and there's something left.
81- // Peek to see if this is the last item.
82- match self . peekable . peek ( ) {
83- Some ( _) => Some ( ( Position :: Middle , item) ) ,
84- None => Some ( ( Position :: Last , item) ) ,
85- }
86- }
87- }
88- // Iterator is finished.
89- None => None ,
90- }
83+ let item = self . peekable . next ( ) ?;
84+
85+ let is_last = self . peekable . peek ( ) . is_none ( ) ;
86+ let is_first = !self . handled_first ;
87+ self . handled_first = true ;
88+
89+ Some ( ( Position { is_first, is_last } , item) )
9190 }
9291
9392 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
@@ -105,18 +104,36 @@ impl<I: Iterator> Iterator for WithPosition<I> {
105104 match self . peekable . next ( ) {
106105 Some ( second) => {
107106 let first = std:: mem:: replace ( & mut head, second) ;
108- init = f ( init, ( Position :: First , first) ) ;
107+ let position = Position {
108+ is_first : true ,
109+ is_last : false ,
110+ } ;
111+ init = f ( init, ( position, first) ) ;
112+ }
113+ None => {
114+ let position = Position {
115+ is_first : true ,
116+ is_last : true ,
117+ } ;
118+ return f ( init, ( position, head) ) ;
109119 }
110- None => return f ( init, ( Position :: Only , head) ) ,
111120 }
112121 }
113122 // Have seen the first item, and there's something left.
114123 init = self . peekable . fold ( init, |acc, mut item| {
115124 std:: mem:: swap ( & mut head, & mut item) ;
116- f ( acc, ( Position :: Middle , item) )
125+ let position = Position {
126+ is_first : false ,
127+ is_last : false ,
128+ } ;
129+ f ( acc, ( position, item) )
117130 } ) ;
131+ let position = Position {
132+ is_first : false ,
133+ is_last : true ,
134+ } ;
118135 // The "head" is now the last item.
119- init = f ( init, ( Position :: Last , head) ) ;
136+ init = f ( init, ( position , head) ) ;
120137 }
121138 init
122139 }
0 commit comments