Peek
trait for peekable iterators · Issue #176 · rust-lang/libs-team (original) (raw)
Proposal
Problem statement
Some iterator types can support peeking à la Peekable
. Sometimes, peeking is required for such an iterator, but methods specific to the original iterator’s type must be called as well. In these cases, creating a Peekable
does not allow doing the latter.
Motivation, use-cases
The following code for ps9 is meant to parse a ‘decoration’ object at the start of a word, returning the parsed object as well as the remainder of the string.
impl Decoration {
/// Parses a [Decoration
] at the beginning of the string,
/// returning it and the remainder of the input.
///
/// This operation always succeeds as it can always parse an
/// empty decoration at the beginning.
///
/// # Examples
///
/// /// let word = "*#feris"; /// let (decoration, remainder) = Decoration::parse(word); /// assert_eq!(decoration.premarker, PreMarker::Carþ); /// assert!(decoration.has_nef); /// assert!(!decoration.has_sen); /// assert_eq!(remainder, "feris"); ///
pub fn parse(s: &str) -> (Decoration, &str) {
let mut s = s.chars().peekable();
let has_nef = s.next_if_eq(&'*').is_some();
let premarker_char = s.next_if(|c| "#+×@".contains(c));
let premarker = match premarker_char {
Some('#') => PreMarker::Carþ,
Some('+') => match s.next_if_eq(&'') {
Some(_) => PreMarker::Njor,
None => PreMarker::Tor,
},
Some('×') => PreMarker::Njor,
Some('@') => PreMarker::Es,
_ => PreMarker::None,
};
let has_sen = s.next_if_eq(&'&').is_some();
(
Decoration {
premarker,
has_nef,
has_sen,
},
// ERROR: no method named as_str
found for struct Peekable
in the current scope
// method not found in Peekable<Chars<'_>>
s.as_str(),
)
}
}
Solution sketches
We could add a Peek: Iterator
trait that would provide the same methods as Peekable
. This trait would be implemented by Peekable
as well as any other iterator that can support peeking operations, such as std::str::Chars
, std::slice::Iter
, and std::ops::Range
.
This trait could be added to all types that are Iterator + Clone
, but this would incur unnecessary overhead for types such as std::vec::IntoIter
which can peek at O(1) time but needs O(n) time to clone.
Links and related work
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.