Remove Features methods
diff --git a/codegen/src/gen.rs b/codegen/src/gen.rs
index 83ddc4e..a51a800 100644
--- a/codegen/src/gen.rs
+++ b/codegen/src/gen.rs
@@ -355,7 +355,7 @@
types::Type::Group(t) => Some(token_group_visit(&t[..], kind, name)),
types::Type::Syn(t) => {
fn requires_full(features: &types::Features) -> bool {
- features.contains("full") && features.len() == 1
+ features.any.contains("full") && features.any.len() == 1
}
let mut res = simple_visit(t, kind, name);
@@ -380,17 +380,11 @@
}
fn visit_features(features: &types::Features) -> TokenStream {
+ let features = &features.any;
match features.len() {
0 => quote!(),
- 1 => {
- let feature = &features[0];
- quote!(#[cfg(feature = #feature)])
- }
- _ => {
- let features = features.iter().map(|feature| quote!(feature = #feature));
-
- quote!(#[cfg(any( #(#features),* ))])
- }
+ 1 => quote!(#[cfg(feature = #(#features)*)]),
+ _ => quote!(#[cfg(any(#(feature = #features),*))]),
}
}
diff --git a/codegen/src/parse.rs b/codegen/src/parse.rs
index 448188d..cdfc7e0 100644
--- a/codegen/src/parse.rs
+++ b/codegen/src/parse.rs
@@ -192,7 +192,15 @@
}
let features: types::Features = syn::parse2(attr.tts.clone()).unwrap();
- ret.join(&features);
+
+ if ret.any.is_empty() {
+ ret = features;
+ } else if ret.any.len() < features.any.len() {
+ assert!(ret.any.iter().all(|f| features.any.contains(f)));
+ } else {
+ assert!(features.any.iter().all(|f| ret.any.contains(f)));
+ ret = features;
+ }
}
ret
@@ -248,7 +256,7 @@
use syn::parse::{Parse, ParseStream, Result};
use syn::*;
- use std::collections::BTreeMap;
+ use std::collections::{BTreeMap, BTreeSet};
fn peek_tag(input: ParseStream, tag: &str) -> bool {
let ahead = input.fork();
@@ -445,7 +453,7 @@
impl Parse for types::Features {
fn parse(input: ParseStream) -> Result<Self> {
- let mut features = vec![];
+ let mut features = BTreeSet::new();
let level_1;
parenthesized!(level_1 in input);
@@ -459,14 +467,14 @@
parenthesized!(level_2 in level_1);
while !level_2.is_empty() {
- features.push(parse_feature(&level_2)?);
+ features.insert(parse_feature(&level_2)?);
if !level_2.is_empty() {
level_2.parse::<Token![,]>()?;
}
}
} else if i == "feature" {
- features.push(parse_feature(&level_1)?);
+ features.insert(parse_feature(&level_1)?);
assert!(level_1.is_empty());
} else {
panic!("{:?}", i);
diff --git a/codegen/src/types.rs b/codegen/src/types.rs
index cc6733c..7be3487 100644
--- a/codegen/src/types.rs
+++ b/codegen/src/types.rs
@@ -1,8 +1,7 @@
use indexmap::IndexMap;
use serde::{Deserialize, Deserializer};
-use std::collections::BTreeMap;
-use std::ops;
+use std::collections::{BTreeMap, BTreeSet};
#[derive(Debug, Clone, PartialEq)]
pub struct Definitions {
@@ -73,41 +72,7 @@
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
pub struct Features {
- pub any: Vec<String>,
-}
-
-impl Features {
- pub fn join(&mut self, other: &Features) {
- if self.any.is_empty() {
- self.any = other.any.clone();
- } else if self.any.len() < other.any.len() {
- assert!(self.any.iter().all(|f| other.any.contains(f)));
- } else {
- assert!(other.any.iter().all(|f| self.any.contains(f)));
-
- self.any = other.any.clone();
- }
- }
-
- pub fn len(&self) -> usize {
- self.any.len()
- }
-
- pub fn contains(&self, tag: &str) -> bool {
- self.iter().any(|s| s == tag)
- }
-
- pub fn iter(&self) -> impl Iterator<Item = &str> {
- self.any.iter().map(|s| &s[..])
- }
-}
-
-impl ops::Index<usize> for Features {
- type Output = str;
-
- fn index(&self, index: usize) -> &str {
- self.any.index(index)
- }
+ pub any: BTreeSet<String>,
}
fn is_private(data: &Data) -> bool {