Skip to content

Commit

Permalink
Support arbitrary containers by IntoIterator blanket impl
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaslihotzki committed Sep 8, 2022
1 parent 2f18cb3 commit a00eb0f
Showing 1 changed file with 14 additions and 61 deletions.
75 changes: 14 additions & 61 deletions src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ pub mod ext {
use super::RepInterp;
use super::{HasIterator as HasIter, ThereIsNoIteratorInRepetition as DoesNotHaveIter};
use crate::ToTokens;
use core::slice;
use std::collections::btree_set::{self, BTreeSet};

/// Extension trait providing the `quote_into_iter` method on iterators.
pub trait RepIteratorExt: Iterator + Sized {
Expand All @@ -60,6 +58,16 @@ pub mod ext {

impl<T: Iterator> RepIteratorExt for T {}

/// Extension trait providing the `quote_into_iter` method on containers
/// implementing IntoIterator.
pub trait RepIntoIteratorExt: IntoIterator + Copy + Sized {
fn quote_into_iter(self) -> (Self::IntoIter, HasIter) {
(self.into_iter(), HasIter)
}
}

impl<T: IntoIterator + Copy> RepIntoIteratorExt for T {}

/// Extension trait providing the `quote_into_iter` method for
/// non-iterable types. These types interpolate the same value in each
/// iteration of the repetition.
Expand All @@ -77,62 +85,6 @@ pub mod ext {
}

impl<T: ToTokens + ?Sized> RepToTokensExt for T {}

/// Extension trait providing the `quote_into_iter` method for types that
/// can be referenced as an iterator.
pub trait RepAsIteratorExt<'q> {
type Iter: Iterator;

fn quote_into_iter(&'q self) -> (Self::Iter, HasIter);
}

impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a T {
type Iter = T::Iter;

fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
<T as RepAsIteratorExt>::quote_into_iter(*self)
}
}

impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a mut T {
type Iter = T::Iter;

fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
<T as RepAsIteratorExt>::quote_into_iter(*self)
}
}

impl<'q, T: 'q> RepAsIteratorExt<'q> for [T] {
type Iter = slice::Iter<'q, T>;

fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
(self.iter(), HasIter)
}
}

impl<'q, T: 'q> RepAsIteratorExt<'q> for Vec<T> {
type Iter = slice::Iter<'q, T>;

fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
(self.iter(), HasIter)
}
}

impl<'q, T: 'q> RepAsIteratorExt<'q> for BTreeSet<T> {
type Iter = btree_set::Iter<'q, T>;

fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
(self.iter(), HasIter)
}
}

impl<'q, T: RepAsIteratorExt<'q>> RepAsIteratorExt<'q> for RepInterp<T> {
type Iter = T::Iter;

fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
self.0.quote_into_iter()
}
}
}

// Helper type used within interpolations to allow for repeated binding names.
Expand All @@ -150,11 +102,12 @@ impl<T> RepInterp<T> {
}
}

impl<T: Iterator> Iterator for RepInterp<T> {
impl<T: IntoIterator> IntoIterator for RepInterp<T> {
type Item = T::Item;
type IntoIter = T::IntoIter;

fn next(&mut self) -> Option<Self::Item> {
self.0.next()
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}

Expand Down

0 comments on commit a00eb0f

Please sign in to comment.