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