use super::*;
pub fn gen(gen: &Gen, def: TypeDef, generics: &[Type], ident: &TokenStream, constraints: &TokenStream, _phantoms: &TokenStream, cfg: &Cfg) -> TokenStream {
match gen.reader.type_def_type_name(def) {
TypeName::IIterator => {
return quote! {
impl<T: ::windows::core::RuntimeType> ::core::iter::Iterator for IIterator<T> {
type Item = T;
fn next(&mut self) -> ::core::option::Option<Self::Item> {
let result = self.Current().ok();
if result.is_some() {
self.MoveNext().ok()?;
}
result
}
}
};
}
TypeName::IIterable => {
return quote! {
impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for IIterable<T> {
type Item = T;
type IntoIter = IIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
::core::iter::IntoIterator::into_iter(&self)
}
}
impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for &IIterable<T> {
type Item = T;
type IntoIter = IIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.First().unwrap()
}
}
};
}
TypeName::IVectorView => {
return quote! {
pub struct VectorViewIterator<T: ::windows::core::RuntimeType + 'static> {
vector: ::core::option::Option<IVectorView<T>>,
current: u32,
}
impl<T: ::windows::core::RuntimeType> VectorViewIterator<T> {
pub fn new(vector: ::core::option::Option<IVectorView<T>>) -> Self {
Self { vector, current: 0 }
}
}
impl<T: ::windows::core::RuntimeType> ::core::iter::Iterator for VectorViewIterator<T> {
type Item = T;
fn next(&mut self) -> ::core::option::Option<Self::Item> {
self.vector.as_ref()
.and_then(|vector| {
vector.GetAt(self.current).ok()
})
.and_then(|result| {
self.current += 1;
Some(result)
})
}
}
impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for IVectorView<T> {
type Item = T;
type IntoIter = VectorViewIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
::core::iter::IntoIterator::into_iter(&self)
}
}
impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for &IVectorView<T> {
type Item = T;
type IntoIter = VectorViewIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
VectorViewIterator::new(::core::option::Option::Some(::core::clone::Clone::clone(self)))
}
}
};
}
TypeName::IVector => {
return quote! {
pub struct VectorIterator<T: ::windows::core::RuntimeType + 'static> {
vector: ::core::option::Option<IVector<T>>,
current: u32,
}
impl<T: ::windows::core::RuntimeType> VectorIterator<T> {
pub fn new(vector: ::core::option::Option<IVector<T>>) -> Self {
Self { vector, current: 0 }
}
}
impl<T: ::windows::core::RuntimeType> ::core::iter::Iterator for VectorIterator<T> {
type Item = T;
fn next(&mut self) -> ::core::option::Option<Self::Item> {
self.vector.as_ref()
.and_then(|vector| {
vector.GetAt(self.current).ok()
})
.and_then(|result| {
self.current += 1;
Some(result)
})
}
}
impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for IVector<T> {
type Item = T;
type IntoIter = VectorIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
::core::iter::IntoIterator::into_iter(&self)
}
}
impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for &IVector<T> {
type Item = T;
type IntoIter = VectorIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
VectorIterator::new(::core::option::Option::Some(::core::clone::Clone::clone(self)))
}
}
};
}
_ => {}
}
let wfc = gen.namespace("Windows.Foundation.Collections");
let mut iterable = None;
let interfaces = gen.reader.type_interfaces(&Type::TypeDef((def, generics.to_vec())));
for interface in interfaces {
if let Type::TypeDef((interface, interface_generics)) = &interface.ty {
match gen.reader.type_def_type_name(*interface) {
TypeName::IVectorView => {
let item = gen.type_name(&interface_generics[0]);
let mut cfg = cfg.clone();
gen.reader.type_def_cfg_combine(*interface, interface_generics, &mut cfg);
let features = gen.cfg_features(&cfg);
return quote! {
#features
impl<#constraints> ::core::iter::IntoIterator for #ident {
type Item = #item;
type IntoIter = #wfc VectorViewIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
::core::iter::IntoIterator::into_iter(&self)
}
}
#features
impl<#constraints> ::core::iter::IntoIterator for &#ident {
type Item = #item;
type IntoIter = #wfc VectorViewIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
#wfc VectorViewIterator::new(::core::convert::TryInto::try_into(self).ok())
}
}
};
}
TypeName::IVector => {
let item = gen.type_name(&interface_generics[0]);
let mut cfg = cfg.clone();
gen.reader.type_def_cfg_combine(*interface, interface_generics, &mut cfg);
let features = gen.cfg_features(&cfg);
return quote! {
#features
impl<#constraints> ::core::iter::IntoIterator for #ident {
type Item = #item;
type IntoIter = #wfc VectorIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
::core::iter::IntoIterator::into_iter(&self)
}
}
#features
impl<#constraints> ::core::iter::IntoIterator for &#ident {
type Item = #item;
type IntoIter = #wfc VectorIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
#wfc VectorIterator::new(::core::convert::TryInto::try_into(self).ok())
}
}
};
}
TypeName::IIterable => {
iterable = Some((*interface, interface_generics.to_vec()));
}
_ => {}
}
}
}
match iterable {
None => TokenStream::new(),
Some((interface, interface_generics)) => {
let item = gen.type_name(&interface_generics[0]);
let mut cfg = cfg.clone();
gen.reader.type_def_cfg_combine(interface, &interface_generics, &mut cfg);
let features = gen.cfg_features(&cfg);
quote! {
#features
impl<#constraints> ::core::iter::IntoIterator for #ident {
type Item = #item;
type IntoIter = #wfc IIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
::core::iter::IntoIterator::into_iter(&self)
}
}
#features
impl<#constraints> ::core::iter::IntoIterator for &#ident {
type Item = #item;
type IntoIter = #wfc IIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.First().unwrap()
}
}
}
}
}
}