From 65fd9a895ba3093f9b5d9d02fb8bd18a9be61808 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 10 Sep 2019 16:00:00 +0200 Subject: Avoid the use of drain_filter feature --- pest_consume_macros/src/lib.rs | 1 - pest_consume_macros/src/make_parser.rs | 32 ++++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) (limited to 'pest_consume_macros') 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 { + fn partition_filter(&mut self, predicate: F) -> Vec + where + F: FnMut(&mut Item) -> bool; +} + +impl VecPartitionFilterExt for Vec { + fn partition_filter(&mut self, mut predicate: F) -> Vec + 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::>() + .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( -- cgit v1.2.3