Skip to content

Commit f6c8757

Browse files
committed
Extract stepping from EscapeUnicode::next
Extract a function that updates the iterator state and returns the result of an arbitrary step of iteration. This implements the same logic as `next`, but it can be shared with `nth`.
1 parent 113b366 commit f6c8757

File tree

1 file changed

+49
-29
lines changed

1 file changed

+49
-29
lines changed

src/libcore/char.rs

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -449,34 +449,10 @@ impl Iterator for EscapeUnicode {
449449
type Item = char;
450450

451451
fn next(&mut self) -> Option<char> {
452-
match self.state {
453-
EscapeUnicodeState::Backslash => {
454-
self.state = EscapeUnicodeState::Type;
455-
Some('\\')
456-
}
457-
EscapeUnicodeState::Type => {
458-
self.state = EscapeUnicodeState::LeftBrace;
459-
Some('u')
460-
}
461-
EscapeUnicodeState::LeftBrace => {
462-
self.state = EscapeUnicodeState::Value;
463-
Some('{')
464-
}
465-
EscapeUnicodeState::Value => {
466-
let c = from_digit(((self.c as u32) >> (self.offset * 4)) & 0xf, 16).unwrap();
467-
if self.offset == 0 {
468-
self.state = EscapeUnicodeState::RightBrace;
469-
} else {
470-
self.offset -= 1;
471-
}
472-
Some(c)
473-
}
474-
EscapeUnicodeState::RightBrace => {
475-
self.state = EscapeUnicodeState::Done;
476-
Some('}')
477-
}
478-
EscapeUnicodeState::Done => None,
479-
}
452+
let state = self.state_len();
453+
let offset = self.offset;
454+
455+
self.step(state, offset)
480456
}
481457

482458
#[inline]
@@ -507,8 +483,15 @@ impl Iterator for EscapeUnicode {
507483
impl ExactSizeIterator for EscapeUnicode {
508484
#[inline]
509485
fn len(&self) -> usize {
486+
self.offset + self.state_len()
487+
}
488+
}
489+
490+
impl EscapeUnicode {
491+
#[inline]
492+
fn state_len(&self) -> usize {
510493
// The match is a single memory access with no branching
511-
self.offset + self.state {
494+
match self.state {
512495
EscapeUnicodeState::Done => 0,
513496
EscapeUnicodeState::RightBrace => 1,
514497
EscapeUnicodeState::Value => 2,
@@ -517,6 +500,43 @@ impl ExactSizeIterator for EscapeUnicode {
517500
EscapeUnicodeState::Backslash => 5,
518501
}
519502
}
503+
504+
#[inline]
505+
fn step(&mut self, state: usize, offset: usize) -> Option<char> {
506+
self.offset = offset;
507+
508+
match state {
509+
5 => {
510+
self.state = EscapeUnicodeState::Type;
511+
Some('\\')
512+
}
513+
4 => {
514+
self.state = EscapeUnicodeState::LeftBrace;
515+
Some('u')
516+
}
517+
3 => {
518+
self.state = EscapeUnicodeState::LeftBrace;
519+
Some('{')
520+
}
521+
2 => {
522+
self.state = if offset == 0 {
523+
EscapeUnicodeState::RightBrace
524+
} else {
525+
self.offset -= 1;
526+
EscapeUnicodeState::Value
527+
};
528+
from_digit(((self.c as u32) >> (offset * 4)) & 0xf, 16)
529+
}
530+
1 => {
531+
self.state = EscapeUnicodeState::Done;
532+
Some('}')
533+
}
534+
_ => {
535+
self.state = EscapeUnicodeState::Done;
536+
None
537+
}
538+
}
539+
}
520540
}
521541

522542
/// An iterator that yields the literal escape code of a `char`.

0 commit comments

Comments
 (0)