Skip to content

Commit 6be798a

Browse files
committed
Implement two-way iterators and peekables
1 parent f129237 commit 6be798a

File tree

3 files changed

+296
-22
lines changed

3 files changed

+296
-22
lines changed

src/iter.rs

+82-22
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ use crate::str_utils::{
7373
last_line_start_byte_idx, line_to_byte_idx, trim_line_break,
7474
};
7575
use crate::tree::{Count, Node, TextInfo};
76+
use crate::two_way_peekable::{TwoWayIterator, TwoWayPeekable};
7677

7778
//==========================================================
7879

@@ -211,16 +212,20 @@ impl<'a> Bytes<'a> {
211212
self
212213
}
213214

215+
/// Return peekable version of the iterator
216+
#[inline(always)]
217+
pub fn two_way_peekable(self) -> TwoWayPeekable<Self> {
218+
// this is needed, so that users can call `.two_way_peekable()` without importing TwoWayIterator
219+
TwoWayIterator::two_way_peekable(self)
220+
}
221+
214222
/// Advances the iterator backwards and returns the previous value.
215223
///
216224
/// Runs in amortized O(1) time and worst-case O(log N) time.
217225
#[inline(always)]
218226
pub fn prev(&mut self) -> Option<u8> {
219-
if !self.is_reversed {
220-
self.prev_impl()
221-
} else {
222-
self.next_impl()
223-
}
227+
// this is needed, so that users can call `.prev()` without importing TwoWayIterator
228+
TwoWayIterator::prev(self)
224229
}
225230

226231
#[inline]
@@ -298,6 +303,16 @@ impl<'a> Iterator for Bytes<'a> {
298303
}
299304
}
300305

306+
impl<'a> TwoWayIterator for Bytes<'a> {
307+
fn prev(&mut self) -> Option<Self::Item> {
308+
if !self.is_reversed {
309+
self.prev_impl()
310+
} else {
311+
self.next_impl()
312+
}
313+
}
314+
}
315+
301316
impl<'a> ExactSizeIterator for Bytes<'a> {}
302317

303318
//==========================================================
@@ -441,16 +456,20 @@ impl<'a> Chars<'a> {
441456
self
442457
}
443458

459+
/// Return peekable version of the iterator
460+
#[inline(always)]
461+
pub fn two_way_peekable(self) -> TwoWayPeekable<Self> {
462+
// this is needed, so that users can call `.two_way_peekable()` without importing TwoWayIterator
463+
TwoWayIterator::two_way_peekable(self)
464+
}
465+
444466
/// Advances the iterator backwards and returns the previous value.
445467
///
446468
/// Runs in amortized O(1) time and worst-case O(log N) time.
447469
#[inline(always)]
448470
pub fn prev(&mut self) -> Option<char> {
449-
if !self.is_reversed {
450-
self.prev_impl()
451-
} else {
452-
self.next_impl()
453-
}
471+
// this is needed, so that users can call `.prev()` without importing TwoWayIterator
472+
TwoWayIterator::prev(self)
454473
}
455474

456475
#[inline]
@@ -536,6 +555,20 @@ impl<'a> Iterator for Chars<'a> {
536555
}
537556
}
538557

558+
impl<'a> TwoWayIterator for Chars<'a> {
559+
/// Advances the iterator backwards and returns the previous value.
560+
///
561+
/// Runs in amortized O(1) time and worst-case O(log N) time.
562+
#[inline(always)]
563+
fn prev(&mut self) -> Option<Self::Item> {
564+
if !self.is_reversed {
565+
self.prev_impl()
566+
} else {
567+
self.next_impl()
568+
}
569+
}
570+
}
571+
539572
impl<'a> ExactSizeIterator for Chars<'a> {}
540573

541574
//==========================================================
@@ -751,17 +784,20 @@ impl<'a> Lines<'a> {
751784
self
752785
}
753786

787+
/// Return peekable version of the iterator
788+
#[inline(always)]
789+
pub fn two_way_peekable(self) -> TwoWayPeekable<Self> {
790+
// this is needed, so that users can call `.two_way_peekable()` without importing TwoWayIterator
791+
TwoWayIterator::two_way_peekable(self)
792+
}
793+
754794
/// Advances the iterator backwards and returns the previous value.
755795
///
756-
/// Runs in O(1) time with respect to rope length and O(N) time with
757-
/// respect to line length.
796+
/// Runs in amortized O(1) time and worst-case O(log N) time.
758797
#[inline(always)]
759798
pub fn prev(&mut self) -> Option<RopeSlice<'a>> {
760-
if self.is_reversed {
761-
self.next_impl()
762-
} else {
763-
self.prev_impl()
764-
}
799+
// this is needed, so that users can call `.prev()` without importing TwoWayIterator
800+
TwoWayIterator::prev(self)
765801
}
766802

767803
fn prev_impl(&mut self) -> Option<RopeSlice<'a>> {
@@ -1244,6 +1280,16 @@ impl<'a> Iterator for Lines<'a> {
12441280
}
12451281
}
12461282

1283+
impl<'a> TwoWayIterator for Lines<'a> {
1284+
fn prev(&mut self) -> Option<Self::Item> {
1285+
if !self.is_reversed {
1286+
self.prev_impl()
1287+
} else {
1288+
self.next_impl()
1289+
}
1290+
}
1291+
}
1292+
12471293
impl ExactSizeIterator for Lines<'_> {}
12481294

12491295
//==========================================================
@@ -1535,16 +1581,20 @@ impl<'a> Chunks<'a> {
15351581
self
15361582
}
15371583

1584+
/// Return peekable version of the iterator
1585+
#[inline(always)]
1586+
pub fn two_way_peekable(self) -> TwoWayPeekable<Self> {
1587+
// this is needed, so that users can call `.two_way_peekable()` without importing TwoWayIterator
1588+
TwoWayIterator::two_way_peekable(self)
1589+
}
1590+
15381591
/// Advances the iterator backwards and returns the previous value.
15391592
///
15401593
/// Runs in amortized O(1) time and worst-case O(log N) time.
15411594
#[inline(always)]
15421595
pub fn prev(&mut self) -> Option<&'a str> {
1543-
if !self.is_reversed {
1544-
self.prev_impl()
1545-
} else {
1546-
self.next_impl()
1547-
}
1596+
// this is needed, so that users can call `.prev()` without importing TwoWayIterator
1597+
TwoWayIterator::prev(self)
15481598
}
15491599

15501600
fn prev_impl(&mut self) -> Option<&'a str> {
@@ -1713,6 +1763,16 @@ impl<'a> Iterator for Chunks<'a> {
17131763
}
17141764
}
17151765

1766+
impl<'a> TwoWayIterator for Chunks<'a> {
1767+
fn prev(&mut self) -> Option<Self::Item> {
1768+
if !self.is_reversed {
1769+
self.prev_impl()
1770+
} else {
1771+
self.next_impl()
1772+
}
1773+
}
1774+
}
1775+
17161776
#[cfg(test)]
17171777
mod tests {
17181778
#![allow(clippy::while_let_on_iterator)]

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ mod tree;
178178

179179
pub mod iter;
180180
pub mod str_utils;
181+
pub mod two_way_peekable;
181182

182183
use std::ops::Bound;
183184

0 commit comments

Comments
 (0)