Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::iter::Peekable;
- struct Join<T, S> {
- container: T,
- separator: S,
- }
- pub struct JoinIter<Iter: Iterator, Sep> {
- iter: Peekable<Iter>,
- sep: Sep,
- next_sep: bool,
- }
- #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
- pub enum JoinItem<T, S> {
- Element(T),
- Separator(S),
- }
- impl<T: IntoIterator, S: Clone> IntoIterator for Join<T, S> {
- type IntoIter = JoinIter<T::IntoIter, S>;
- type Item = JoinItem<T::Item, S>;
- fn into_iter(self) -> Self::IntoIter {
- JoinIter::new(self.container.into_iter(), self.separator)
- }
- }
- impl<'a, T, S> IntoIterator for &'a Join<T, S>
- where &'a T: IntoIterator
- {
- type IntoIter = JoinIter<<&'a T as IntoIterator>::IntoIter, &'a S>;
- type Item = JoinItem<<&'a T as IntoIterator>::Item, &'a S>;
- fn into_iter(self) -> Self::IntoIter {
- JoinIter::new(self.container.into_iter(), &self.separator)
- }
- }
- impl<T, S> Join<T, S>
- where for<'a> &'a T: IntoIterator
- {
- fn iter(&self) -> JoinIter<<&T as IntoIterator>::IntoIter, &S> {
- self.into_iter()
- }
- }
- impl<I: Iterator, S: Clone> Iterator for JoinIter<I, S> {
- type Item = JoinItem<I::Item, S>;
- /// Advance to the next item in the Join. This will either be the next
- /// element in the underlying iterator, or a clone of the separator.
- fn next(&mut self) -> Option<Self::Item> {
- let sep = &self.sep;
- let next_sep = &mut self.next_sep;
- if *next_sep {
- self.iter.peek().map(|_| {
- *next_sep = false;
- JoinItem::Separator(sep.clone())
- })
- } else {
- self.iter.next().map(|element| {
- *next_sep = true;
- JoinItem::Element(element)
- })
- }
- }
- }
- fn main() {
- // Create a join struct
- let join = vec![1, 2, 3].join_with(", ");
- // This line fails to compile
- let iter = join.iter();
- }
Add Comment
Please, Sign In to add comment