forked from libre-chip/fayalite
		
	add Iterator<Item = Pair<T, P>> helpers
This commit is contained in:
		
							parent
							
								
									c94a437686
								
							
						
					
					
						commit
						7963f0a5cd
					
				
					 3 changed files with 140 additions and 45 deletions
				
			
		|  | @ -7,7 +7,9 @@ use std::io::{ErrorKind, Write}; | |||
| use syn::{ | ||||
|     bracketed, parenthesized, | ||||
|     parse::{Parse, ParseStream, Parser}, | ||||
|     parse_quote, AttrStyle, Attribute, Error, Item, Token, | ||||
|     parse_quote, | ||||
|     punctuated::Pair, | ||||
|     AttrStyle, Attribute, Error, Item, Token, | ||||
| }; | ||||
| 
 | ||||
| mod fold; | ||||
|  | @ -318,6 +320,108 @@ impl<T: Parse> HdlAttr<T> { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #[allow(dead_code)] | ||||
| pub(crate) trait PairsIterExt: Sized + Iterator { | ||||
|     fn map_pair<T1, T2, P1, P2, ValueFn: FnMut(T1) -> T2, PunctFn: FnMut(P1) -> P2>( | ||||
|         self, | ||||
|         mut value_fn: ValueFn, | ||||
|         mut punct_fn: PunctFn, | ||||
|     ) -> impl Iterator<Item = Pair<T2, P2>> | ||||
|     where | ||||
|         Self: Iterator<Item = Pair<T1, P1>>, | ||||
|     { | ||||
|         self.map(move |p| { | ||||
|             let (t, p) = p.into_tuple(); | ||||
|             let t = value_fn(t); | ||||
|             let p = p.map(&mut punct_fn); | ||||
|             Pair::new(t, p) | ||||
|         }) | ||||
|     } | ||||
|     fn filter_map_pair<T1, T2, P1, P2, ValueFn: FnMut(T1) -> Option<T2>, PunctFn: FnMut(P1) -> P2>( | ||||
|         self, | ||||
|         mut value_fn: ValueFn, | ||||
|         mut punct_fn: PunctFn, | ||||
|     ) -> impl Iterator<Item = Pair<T2, P2>> | ||||
|     where | ||||
|         Self: Iterator<Item = Pair<T1, P1>>, | ||||
|     { | ||||
|         self.filter_map(move |p| { | ||||
|             let (t, p) = p.into_tuple(); | ||||
|             let t = value_fn(t)?; | ||||
|             let p = p.map(&mut punct_fn); | ||||
|             Some(Pair::new(t, p)) | ||||
|         }) | ||||
|     } | ||||
|     fn map_pair_value<T1, T2, P, F: FnMut(T1) -> T2>( | ||||
|         self, | ||||
|         f: F, | ||||
|     ) -> impl Iterator<Item = Pair<T2, P>> | ||||
|     where | ||||
|         Self: Iterator<Item = Pair<T1, P>>, | ||||
|     { | ||||
|         self.map_pair(f, |v| v) | ||||
|     } | ||||
|     fn filter_map_pair_value<T1, T2, P, F: FnMut(T1) -> Option<T2>>( | ||||
|         self, | ||||
|         f: F, | ||||
|     ) -> impl Iterator<Item = Pair<T2, P>> | ||||
|     where | ||||
|         Self: Iterator<Item = Pair<T1, P>>, | ||||
|     { | ||||
|         self.filter_map_pair(f, |v| v) | ||||
|     } | ||||
|     fn map_pair_value_mut<'a, T1: 'a, T2: 'a, P: Clone + 'a, F: FnMut(T1) -> T2 + 'a>( | ||||
|         self, | ||||
|         f: F, | ||||
|     ) -> impl Iterator<Item = Pair<T2, P>> + 'a | ||||
|     where | ||||
|         Self: Iterator<Item = Pair<T1, &'a mut P>> + 'a, | ||||
|     { | ||||
|         self.map_pair(f, |v| v.clone()) | ||||
|     } | ||||
|     fn filter_map_pair_value_mut< | ||||
|         'a, | ||||
|         T1: 'a, | ||||
|         T2: 'a, | ||||
|         P: Clone + 'a, | ||||
|         F: FnMut(T1) -> Option<T2> + 'a, | ||||
|     >( | ||||
|         self, | ||||
|         f: F, | ||||
|     ) -> impl Iterator<Item = Pair<T2, P>> + 'a | ||||
|     where | ||||
|         Self: Iterator<Item = Pair<T1, &'a mut P>> + 'a, | ||||
|     { | ||||
|         self.filter_map_pair(f, |v| v.clone()) | ||||
|     } | ||||
|     fn map_pair_value_ref<'a, T1: 'a, T2: 'a, P: Clone + 'a, F: FnMut(T1) -> T2 + 'a>( | ||||
|         self, | ||||
|         f: F, | ||||
|     ) -> impl Iterator<Item = Pair<T2, P>> + 'a | ||||
|     where | ||||
|         Self: Iterator<Item = Pair<T1, &'a P>> + 'a, | ||||
|     { | ||||
|         self.map_pair(f, |v| v.clone()) | ||||
|     } | ||||
|     fn filter_map_pair_value_ref< | ||||
|         'a, | ||||
|         T1: 'a, | ||||
|         T2: 'a, | ||||
|         P: Clone + 'a, | ||||
|         F: FnMut(T1) -> Option<T2> + 'a, | ||||
|     >( | ||||
|         self, | ||||
|         f: F, | ||||
|     ) -> impl Iterator<Item = Pair<T2, P>> + 'a | ||||
|     where | ||||
|         Self: Iterator<Item = Pair<T1, &'a P>> + 'a, | ||||
|     { | ||||
|         self.filter_map_pair(f, |v| v.clone()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T, P, Iter: Iterator<Item = Pair<T, P>>> PairsIterExt for Iter {} | ||||
| 
 | ||||
| pub(crate) struct Errors { | ||||
|     error: Option<Error>, | ||||
|     finished: bool, | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| // SPDX-License-Identifier: LGPL-3.0-or-later
 | ||||
| // See Notices.txt for copyright information
 | ||||
| use crate::{module::transform_body::Visitor, options, Errors, HdlAttr}; | ||||
| use crate::{module::transform_body::Visitor, options, Errors, HdlAttr, PairsIterExt}; | ||||
| use proc_macro2::{Span, TokenStream}; | ||||
| use quote::{format_ident, quote_spanned, ToTokens, TokenStreamExt}; | ||||
| use syn::{ | ||||
|  | @ -207,7 +207,7 @@ impl StructOrEnumLiteral { | |||
|     } | ||||
|     pub(crate) fn map_fields( | ||||
|         self, | ||||
|         mut f: impl FnMut(StructOrEnumLiteralField) -> StructOrEnumLiteralField, | ||||
|         f: impl FnMut(StructOrEnumLiteralField) -> StructOrEnumLiteralField, | ||||
|     ) -> Self { | ||||
|         let Self { | ||||
|             attrs, | ||||
|  | @ -217,10 +217,7 @@ impl StructOrEnumLiteral { | |||
|             dot2_token, | ||||
|             rest, | ||||
|         } = self; | ||||
|         let fields = Punctuated::from_iter(fields.into_pairs().map(|p| { | ||||
|             let (field, comma) = p.into_tuple(); | ||||
|             Pair::new(f(field), comma) | ||||
|         })); | ||||
|         let fields = fields.into_pairs().map_pair_value(f).collect(); | ||||
|         Self { | ||||
|             attrs, | ||||
|             path, | ||||
|  | @ -247,26 +244,22 @@ impl From<ExprStruct> for StructOrEnumLiteral { | |||
|             attrs, | ||||
|             path: TypePath { qself, path }, | ||||
|             brace_or_paren: BraceOrParen::Brace(brace_token), | ||||
|             fields: Punctuated::from_iter(fields.into_pairs().map(|v| { | ||||
|                 let ( | ||||
|                     FieldValue { | ||||
|             fields: fields | ||||
|                 .into_pairs() | ||||
|                 .map_pair_value( | ||||
|                     |FieldValue { | ||||
|                          attrs, | ||||
|                          member, | ||||
|                          colon_token, | ||||
|                          expr, | ||||
|                      }| StructOrEnumLiteralField { | ||||
|                         attrs, | ||||
|                         member, | ||||
|                         colon_token, | ||||
|                         expr, | ||||
|                     }, | ||||
|                     comma, | ||||
|                 ) = v.into_tuple(); | ||||
|                 Pair::new( | ||||
|                     StructOrEnumLiteralField { | ||||
|                         attrs, | ||||
|                         member, | ||||
|                         colon_token, | ||||
|                         expr, | ||||
|                     }, | ||||
|                     comma, | ||||
|                 ) | ||||
|             })), | ||||
|                 .collect(), | ||||
|             dot2_token, | ||||
|             rest, | ||||
|         } | ||||
|  | @ -514,20 +507,24 @@ impl Visitor { | |||
|                 } | ||||
|             }; | ||||
|         }; | ||||
|         let fields = Punctuated::from_iter(args.into_pairs().enumerate().map(|(index, p)| { | ||||
|             let (expr, comma) = p.into_tuple(); | ||||
|             let mut index = Index::from(index); | ||||
|             index.span = hdl_attr.hdl.span; | ||||
|             Pair::new( | ||||
|                 StructOrEnumLiteralField { | ||||
|                     attrs: vec![], | ||||
|                     member: Member::Unnamed(index), | ||||
|                     colon_token: None, | ||||
|                     expr, | ||||
|                 }, | ||||
|                 comma, | ||||
|             ) | ||||
|         })); | ||||
|         let fields = args | ||||
|             .into_pairs() | ||||
|             .enumerate() | ||||
|             .map(|(index, p)| { | ||||
|                 let (expr, comma) = p.into_tuple(); | ||||
|                 let mut index = Index::from(index); | ||||
|                 index.span = hdl_attr.hdl.span; | ||||
|                 Pair::new( | ||||
|                     StructOrEnumLiteralField { | ||||
|                         attrs: vec![], | ||||
|                         member: Member::Unnamed(index), | ||||
|                         colon_token: None, | ||||
|                         expr, | ||||
|                     }, | ||||
|                     comma, | ||||
|                 ) | ||||
|             }) | ||||
|             .collect(); | ||||
|         self.process_struct_enum( | ||||
|             hdl_attr, | ||||
|             StructOrEnumLiteral { | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ use crate::{ | |||
|         expand_aggregate_literals::{AggregateLiteralOptions, StructOrEnumPath}, | ||||
|         with_debug_clone_and_fold, Visitor, | ||||
|     }, | ||||
|     Errors, HdlAttr, | ||||
|     Errors, HdlAttr, PairsIterExt, | ||||
| }; | ||||
| use proc_macro2::{Span, TokenStream}; | ||||
| use quote::{ToTokens, TokenStreamExt}; | ||||
|  | @ -238,11 +238,7 @@ trait ParseMatchPat: Sized { | |||
|                 leading_vert, | ||||
|                 cases: cases | ||||
|                     .into_pairs() | ||||
|                     .filter_map(|pair| { | ||||
|                         let (pat, punct) = pair.into_tuple(); | ||||
|                         let pat = Self::parse(state, pat).ok()?; | ||||
|                         Some(Pair::new(pat, punct)) | ||||
|                     }) | ||||
|                     .filter_map_pair_value(|pat| Self::parse(state, pat).ok()) | ||||
|                     .collect(), | ||||
|             })), | ||||
|             Pat::Paren(PatParen { | ||||
|  | @ -282,10 +278,8 @@ trait ParseMatchPat: Sized { | |||
|             }) => { | ||||
|                 let fields = fields | ||||
|                     .into_pairs() | ||||
|                     .filter_map(|pair| { | ||||
|                         let (field_pat, punct) = pair.into_tuple(); | ||||
|                         let field_pat = MatchPatStructField::parse(state, field_pat).ok()?; | ||||
|                         Some(Pair::new(field_pat, punct)) | ||||
|                     .filter_map_pair_value(|field_pat| { | ||||
|                         MatchPatStructField::parse(state, field_pat).ok() | ||||
|                     }) | ||||
|                     .collect(); | ||||
|                 let path = TypePath { qself, path }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue