use crate::*;
use squote::{quote, TokenStream};
pub fn gen_iterator(name: &TypeName, interfaces: &[RequiredInterface]) -> TokenStream {
if name.name == "IIterator`1" && name.namespace == "Windows.Foundation.Collections" {
return quote! {
impl<T: ::windows::RuntimeType> ::std::iter::Iterator for IIterator<T> {
type Item = T;
fn next(&mut self) -> ::std::option::Option<Self::Item> {
let result = self.current().ok();
if result.is_some() {
self.move_next().ok()?;
}
result
}
}
};
}
if name.name == "IIterable`1" && name.namespace == "Windows.Foundation.Collections" {
return quote! {
impl<T: ::windows::RuntimeType> ::std::iter::IntoIterator for IIterable<T> {
type Item = T;
type IntoIter = IIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.first().unwrap()
}
}
impl<'a, T: ::windows::RuntimeType> ::std::iter::IntoIterator for &'a IIterable<T> {
type Item = T;
type IntoIter = IIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.first().unwrap()
}
}
};
}
if name.name == "IVectorView`1" && name.namespace == "Windows.Foundation.Collections" {
return quote! {
pub struct VectorViewIterator<T: ::windows::RuntimeType + 'static> {
vector: IVectorView<T>,
current: u32,
size: u32,
}
impl<T: ::windows::RuntimeType> VectorViewIterator<T> {
pub fn new(vector: IVectorView<T>) -> Self {
let size = vector.size().unwrap();
Self { vector, current: 0, size }
}
}
impl<T: ::windows::RuntimeType> ::std::iter::Iterator for VectorViewIterator<T> {
type Item = T;
fn next(&mut self) -> ::std::option::Option<Self::Item> {
if self.current >= self.size {
return None;
}
let result = self.vector.get_at(self.current);
self.current += 1;
result.ok()
}
}
impl<T: ::windows::RuntimeType> ::std::iter::IntoIterator for IVectorView<T> {
type Item = T;
type IntoIter = VectorViewIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
VectorViewIterator::new(self)
}
}
impl<'a, T: ::windows::RuntimeType> ::std::iter::IntoIterator for &'a IVectorView<T> {
type Item = T;
type IntoIter = VectorViewIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
VectorViewIterator::new(::std::clone::Clone::clone(self))
}
}
};
}
if name.name == "IVector`1" && name.namespace == "Windows.Foundation.Collections" {
return quote! {
pub struct VectorIterator<T: ::windows::RuntimeType + 'static> {
vector: IVector<T>,
current: u32,
size: u32,
}
impl<T: ::windows::RuntimeType> VectorIterator<T> {
pub fn new(vector: IVector<T>) -> Self {
let size = vector.size().unwrap();
Self { vector, current: 0, size }
}
}
impl<T: ::windows::RuntimeType> ::std::iter::Iterator for VectorIterator<T> {
type Item = T;
fn next(&mut self) -> ::std::option::Option<Self::Item> {
if self.current >= self.size {
return None;
}
let result = self.vector.get_at(self.current);
self.current += 1;
result.ok()
}
}
impl<T: ::windows::RuntimeType> ::std::iter::IntoIterator for IVector<T> {
type Item = T;
type IntoIter = VectorIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
VectorIterator::new(self)
}
}
impl<'a, T: ::windows::RuntimeType> ::std::iter::IntoIterator for &'a IVector<T> {
type Item = T;
type IntoIter = VectorIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
VectorIterator::new(::std::clone::Clone::clone(self))
}
}
};
}
let mut iterable = None;
for interface in interfaces {
if interface.name.name == "IVectorView`1"
&& interface.name.namespace == "Windows.Foundation.Collections"
{
let item = interface.name.generics[0].gen();
let wfc = gen_namespace(&interface.name.namespace, &name.namespace);
let name = name.gen();
return quote! {
impl ::std::iter::IntoIterator for #name {
type Item = #item;
type IntoIter = #wfc VectorViewIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
#wfc VectorViewIterator::new(self.into())
}
}
impl<'a> ::std::iter::IntoIterator for &'a #name {
type Item = #item;
type IntoIter = #wfc VectorViewIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
#wfc VectorViewIterator::new(self.into())
}
}
};
}
if interface.name.name == "IVectorView`1"
&& interface.name.namespace == "Windows.Foundation.Collections"
{
let item = interface.name.generics[0].gen();
let wfc = gen_namespace(&interface.name.namespace, &name.namespace);
let name = name.gen();
return quote! {
impl ::std::iter::IntoIterator for #name {
type Item = #item;
type IntoIter = #wfc VectorIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
#wfc VectorIterator::new(self.into())
}
}
impl<'a> ::std::iter::IntoIterator for &'a #name {
type Item = #item;
type IntoIter = #wfc VectorIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
#wfc VectorIterator::new(self.into())
}
}
};
}
if interface.name.name == "IIterable`1"
&& interface.name.namespace == "Windows.Foundation.Collections"
{
iterable = Some(interface);
}
}
match iterable {
None => TokenStream::new(),
Some(interface) => {
let constraints = name.gen_constraint();
let item = interface.name.generics[0].gen();
let wfc = gen_namespace(&interface.name.namespace, &name.namespace);
let name = name.gen();
quote! {
impl<#constraints> ::std::iter::IntoIterator for #name {
type Item = #item;
type IntoIter = #wfc IIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.first().unwrap()
}
}
impl<'a, #constraints> ::std::iter::IntoIterator for &'a #name {
type Item = #item;
type IntoIter = #wfc IIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.first().unwrap()
}
}
}
}
}
}