summaryrefslogtreecommitdiff
path: root/pest_consume_macros
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--pest_consume_macros/src/lib.rs1
-rw-r--r--pest_consume_macros/src/make_parser.rs32
2 files changed, 28 insertions, 5 deletions
diff --git a/pest_consume_macros/src/lib.rs b/pest_consume_macros/src/lib.rs
index 3929974..db21f37 100644
--- a/pest_consume_macros/src/lib.rs
+++ b/pest_consume_macros/src/lib.rs
@@ -1,4 +1,3 @@
-#![feature(drain_filter)]
//! This crate contains the code-generation primitives for the [dhall-rust][dhall-rust] crate.
//! This is highly unstable and breaks regularly; use at your own risk.
//!
diff --git a/pest_consume_macros/src/make_parser.rs b/pest_consume_macros/src/make_parser.rs
index 8a15deb..4165046 100644
--- a/pest_consume_macros/src/make_parser.rs
+++ b/pest_consume_macros/src/make_parser.rs
@@ -9,6 +9,32 @@ use syn::{
LitBool, Pat, Path, Token,
};
+/// Ext. trait adding `partition_filter` to `Vec`. Would like to use `Vec::drain_filter`
+/// but it's unstable for now.
+pub trait VecPartitionFilterExt<Item> {
+ fn partition_filter<F>(&mut self, predicate: F) -> Vec<Item>
+ where
+ F: FnMut(&mut Item) -> bool;
+}
+
+impl<Item> VecPartitionFilterExt<Item> for Vec<Item> {
+ fn partition_filter<F>(&mut self, mut predicate: F) -> Vec<Item>
+ where
+ F: FnMut(&mut Item) -> bool,
+ {
+ let mut ret = Vec::new();
+ let mut i = 0;
+ while i != self.len() {
+ if predicate(&mut self[i]) {
+ ret.push(self.remove(i))
+ } else {
+ i += 1;
+ }
+ }
+ ret
+ }
+}
+
mod kw {
syn::custom_keyword!(shortcut);
}
@@ -99,8 +125,7 @@ fn collect_aliases(
let fn_name = function.sig.ident.clone();
let mut alias_attrs = function
.attrs
- .drain_filter(|attr| attr.path.is_ident("alias"))
- .collect::<Vec<_>>()
+ .partition_filter(|attr| attr.path.is_ident("alias"))
.into_iter();
if let Some(attr) = alias_attrs.next() {
@@ -172,8 +197,7 @@ fn apply_special_attrs(f: &mut ParsedFn, rule_enum: &Path) -> Result<()> {
// `prec_climb` attr
let prec_climb_attrs: Vec<_> = function
.attrs
- .drain_filter(|attr| attr.path.is_ident("prec_climb"))
- .collect();
+ .partition_filter(|attr| attr.path.is_ident("prec_climb"));
if prec_climb_attrs.len() > 1 {
return Err(Error::new(