From 5e3c70d4494bbb9bd1f273a41604525a7fa00db6 Mon Sep 17 00:00:00 2001 From: fancyflame Date: Fri, 9 Aug 2024 10:38:51 +0800 Subject: [PATCH] Add `Fields::iter_member` --- src/data.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/data.rs b/src/data.rs index a44cdf341d..3a85626436 100644 --- a/src/data.rs +++ b/src/data.rs @@ -3,6 +3,7 @@ use crate::expr::Expr; use crate::ident::Ident; use crate::punctuated::{self, Punctuated}; use crate::restriction::{FieldMutability, Visibility}; +use crate::spanned::Spanned; use crate::token; use crate::ty::Type; @@ -106,6 +107,54 @@ impl Fields { } } +#[cfg(any(feature = "full", feature = "derive"))] +mod iter_member { + use super::*; + use crate::Member; + + impl Fields { + /// Get an iterator over the fields of a struct or variant as [`Member`]s. + /// This iterator can be used to iterate over a named or unnamed struct or + /// variant's fields uniformly. + /// + /// The return type can considered as impl [`Iterator`]. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + pub fn iter_member(&self) -> IterMember { + IterMember { + iter: self.iter(), + unnamed_counter: 0, + } + } + } + + /// An iterator over the fields of a struct or variant as [`Member`]s. + #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] + #[derive(Clone)] + pub struct IterMember<'a> { + iter: punctuated::Iter<'a, Field>, + unnamed_counter: u32, + } + + impl<'a> Iterator for IterMember<'a> { + type Item = Member; + + fn next(&mut self) -> Option { + let field = self.iter.next()?; + match &field.ident { + Some(ident) => Some(Member::Named(ident.clone())), + None => { + let m = Member::Unnamed(crate::Index { + index: self.unnamed_counter, + span: field.ty.span(), + }); + self.unnamed_counter += 1; + Some(m) + } + } + } + } +} + impl IntoIterator for Fields { type Item = Field; type IntoIter = punctuated::IntoIter;