use crate::{
ir,
InkItemTrait,
InkTraitItem,
InkTraitMessage,
Selector,
};
use std::collections::HashMap;
pub struct IterInkTraitItemsRaw<'a> {
iter: core::slice::Iter<'a, syn::TraitItem>,
}
impl<'a> IterInkTraitItemsRaw<'a> {
pub(super) fn from_raw(item_trait: &'a syn::ItemTrait) -> Self {
Self {
iter: item_trait.items.iter(),
}
}
}
impl<'a> Iterator for IterInkTraitItemsRaw<'a> {
type Item = InkTraitItem<'a>;
fn next(&mut self) -> Option<Self::Item> {
'outer: loop {
match self.iter.next() {
None => return None,
Some(syn::TraitItem::Fn(function)) => {
let first_attr = ir::first_ink_attribute(&function.attrs)
.ok()
.flatten()
.expect("unexpected missing ink! attribute for trait method")
.first()
.kind()
.clone();
match first_attr {
ir::AttributeArg::Message => {
return Some(InkTraitItem::Message(InkTraitMessage::new(
function,
)))
}
_ => continue 'outer,
}
}
Some(_) => continue 'outer,
}
}
}
}
pub struct IterInkTraitItems<'a> {
iter: IterInkTraitItemsRaw<'a>,
message_selectors: &'a HashMap<syn::Ident, Selector>,
}
impl<'a> IterInkTraitItems<'a> {
pub(super) fn new(item_trait: &'a InkItemTrait) -> Self {
Self {
iter: IterInkTraitItemsRaw::from_raw(&item_trait.item),
message_selectors: &item_trait.message_selectors,
}
}
}
impl<'a> Iterator for IterInkTraitItems<'a> {
type Item = (InkTraitItem<'a>, Selector);
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|item| {
let selector = self.message_selectors[item.ident()];
(item, selector)
})
}
}