Remove some surface area from Delimited api
diff --git a/src/attr.rs b/src/attr.rs
index 375904e..13e1867 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -65,7 +65,7 @@
/// Parses the tokens after the path as a [`MetaItem`](enum.MetaItem.html) if possible.
pub fn meta_item(&self) -> Option<MetaItem> {
let name = if self.path.segments.len() == 1 {
- &self.path.segments.get(0).item().ident
+ &self.path.segments.first().unwrap().item().ident
} else {
return None;
};
@@ -187,10 +187,10 @@
Some(pair) => pair,
None => return None,
};
- match prev_comma {
- Some(comma) => delimited.push_next(nested, comma),
- None => delimited.push_first(nested),
+ if let Some(comma) = prev_comma {
+ delimited.push_trailing(comma);
}
+ delimited.push(nested);
tts = rest;
}
diff --git a/src/delimited.rs b/src/delimited.rs
index ec753e8..2136f03 100644
--- a/src/delimited.rs
+++ b/src/delimited.rs
@@ -23,22 +23,6 @@
self.inner.len()
}
- pub fn get(&self, idx: usize) -> Element<&T, &D> {
- let (ref t, ref d) = self.inner[idx];
- match *d {
- Some(ref d) => Element::Delimited(t, d),
- None => Element::End(t),
- }
- }
-
- pub fn get_mut(&mut self, idx: usize) -> Element<&mut T, &mut D> {
- let (ref mut t, ref mut d) = self.inner[idx];
- match *d {
- Some(ref mut d) => Element::Delimited(t, d),
- None => Element::End(t),
- }
- }
-
pub fn first(&self) -> Option<Element<&T, &D>> {
self.inner.first().map(|&(ref t, ref d)| match *d {
Some(ref d) => Element::Delimited(t, d),
@@ -46,15 +30,6 @@
})
}
- pub fn first_mut(&mut self) -> Option<Element<&mut T, &mut D>> {
- self.inner
- .first_mut()
- .map(|&mut (ref mut t, ref mut d)| match *d {
- Some(ref mut d) => Element::Delimited(t, d),
- None => Element::End(t),
- })
- }
-
pub fn last(&self) -> Option<Element<&T, &D>> {
self.inner.last().map(|&(ref t, ref d)| match *d {
Some(ref d) => Element::Delimited(t, d),
@@ -83,60 +58,24 @@
}
}
- pub fn items(&self) -> Items<T, D> {
- Items {
- inner: self.inner.iter(),
- }
- }
-
- pub fn push(&mut self, token: Element<T, D>) {
+ pub fn push(&mut self, token: T) {
assert!(self.empty_or_trailing());
- match token {
- Element::Delimited(t, d) => self.inner.push((t, Some(d))),
- Element::End(t) => self.inner.push((t, None)),
- }
- }
-
- pub fn push_first(&mut self, token: T) {
- assert!(self.is_empty());
- self.inner.push((token, None));
- }
-
- pub fn push_next(&mut self, token: T, delimiter: D) {
- self.push_trailing(delimiter);
self.inner.push((token, None));
}
pub fn push_trailing(&mut self, delimiter: D) {
- let len = self.len();
- assert!(self.inner[len - 1].1.is_none());
- self.inner[len - 1].1 = Some(delimiter);
- }
-
- pub fn push_default(&mut self, token: T)
- where
- D: Default,
- {
- if self.empty_or_trailing() {
- self.inner.push((token, None));
- } else {
- self.push_next(token, D::default());
- }
+ assert!(!self.is_empty());
+ let last = self.inner.last_mut().unwrap();
+ assert!(last.1.is_none());
+ last.1 = Some(delimiter);
}
pub fn pop(&mut self) -> Option<Element<T, D>> {
- self.inner.pop().map(|e| match e {
- (t, Some(d)) => Element::Delimited(t, d),
- (t, None) => Element::End(t),
- })
- }
-
- pub fn into_vec(self) -> Vec<T> {
- self.inner.into_iter().map(|t| t.0).collect()
+ self.inner.pop().map(|(t, d)| Element::new(t, d))
}
pub fn trailing_delim(&self) -> bool {
- self.inner[self.inner.len() - 1].1.is_some()
+ self.inner.last().map(|last| last.1.is_some()).unwrap_or(false)
}
/// Returns true if either this `Delimited` is empty, or it has a trailing
@@ -144,7 +83,7 @@
///
/// Equivalent to `delimited.is_empty() || delimited.trailing_delim()`.
pub fn empty_or_trailing(&self) -> bool {
- self.is_empty() || self.trailing_delim()
+ self.inner.last().map(|last| last.1.is_some()).unwrap_or(true)
}
}
@@ -155,36 +94,6 @@
}
}
-impl<T, D> From<Vec<(T, Option<D>)>> for Delimited<T, D> {
- fn from(v: Vec<(T, Option<D>)>) -> Self {
- Delimited { inner: v }
- }
-}
-
-impl<T, D> From<Vec<T>> for Delimited<T, D>
-where
- D: Default,
-{
- fn from(v: Vec<T>) -> Self {
- let len = v.len();
- Delimited {
- inner: v.into_iter()
- .enumerate()
- .map(|(i, item)| {
- (
- item,
- if i + 1 == len {
- None
- } else {
- Some(D::default())
- },
- )
- })
- .collect(),
- }
- }
-}
-
impl<T, D> FromIterator<Element<T, D>> for Delimited<T, D> {
fn from_iter<I: IntoIterator<Item = Element<T, D>>>(i: I) -> Self {
let mut ret = Delimited::new();
@@ -193,21 +102,10 @@
}
}
-impl<T, D> FromIterator<T> for Delimited<T, D>
-where
- D: Default,
-{
- fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
- let mut ret = Delimited::new();
- ret.extend(i);
- ret
- }
-}
-
impl<T, D> Extend<Element<T, D>> for Delimited<T, D> {
fn extend<I: IntoIterator<Item = Element<T, D>>>(&mut self, i: I) {
- for element in i {
- match element {
+ for elem in i {
+ match elem {
Element::Delimited(a, b) => self.inner.push((a, Some(b))),
Element::End(a) => self.inner.push((a, None)),
}
@@ -215,23 +113,12 @@
}
}
-impl<T, D> Extend<T> for Delimited<T, D>
-where
- D: Default,
-{
- fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
- for element in i {
- self.push_default(element);
- }
- }
-}
-
impl<'a, T, D> IntoIterator for &'a Delimited<T, D> {
type Item = Element<&'a T, &'a D>;
type IntoIter = Iter<'a, T, D>;
fn into_iter(self) -> Self::IntoIter {
- <Delimited<T, D>>::iter(self)
+ Delimited::iter(self)
}
}
@@ -240,7 +127,7 @@
type IntoIter = IterMut<'a, T, D>;
fn into_iter(self) -> Self::IntoIter {
- <Delimited<T, D>>::iter_mut(self)
+ Delimited::iter_mut(self)
}
}
@@ -291,18 +178,6 @@
}
}
-pub struct Items<'a, T: 'a, D: 'a> {
- inner: slice::Iter<'a, (T, Option<D>)>,
-}
-
-impl<'a, T, D> Iterator for Items<'a, T, D> {
- type Item = &'a T;
-
- fn next(&mut self) -> Option<&'a T> {
- self.inner.next().map(|pair| &pair.0)
- }
-}
-
pub struct IntoIter<T, D> {
inner: vec::IntoIter<(T, Option<D>)>,
}
@@ -349,6 +224,13 @@
}
}
+ pub fn new(t: T, d: Option<D>) -> Self {
+ match d {
+ Some(d) => Element::Delimited(t, d),
+ None => Element::End(t),
+ }
+ }
+
pub fn into_tuple(self) -> (T, Option<D>) {
match self {
Element::Delimited(t, d) => (t, Some(d)),
@@ -440,7 +322,7 @@
return parse_error();
}
input = i;
- res.push_first(o);
+ res.push(o);
// get the separator first
while let Ok((i2, s)) = D::parse(input) {
@@ -453,7 +335,8 @@
if i3 == i2 {
break;
}
- res.push_next(o3, s);
+ res.push_trailing(s);
+ res.push(o3);
input = i3;
} else {
break;
diff --git a/src/gen_helper.rs b/src/gen_helper.rs
index 4970805..fdf86a0 100644
--- a/src/gen_helper.rs
+++ b/src/gen_helper.rs
@@ -1,6 +1,6 @@
#[cfg(feature = "fold")]
pub mod fold {
- use delimited::Delimited;
+ use delimited::{Delimited, Element};
use fold::Folder;
use proc_macro2::Span;
@@ -19,10 +19,10 @@
impl<T, U> FoldHelper for Delimited<T, U> {
type Item = T;
fn lift<F>(self, mut f: F) -> Self where F: FnMut(Self::Item) -> Self::Item {
- self.into_iter().map(|elem| {
- let (t, u) = elem.into_tuple();
- (f(t), u)
- }).collect::<Vec<(T, Option<U>)>>().into()
+ self.into_iter()
+ .map(Element::into_tuple)
+ .map(|(t, u)| Element::new(f(t), u))
+ .collect()
}
}
diff --git a/src/generics.rs b/src/generics.rs
index 9caf750..349a46c 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -217,13 +217,12 @@
lt_token: lt,
params: lifetimes.into_iter()
.map(Element::into_tuple)
- .map(|(lifetime, comma)| (GenericParam::Lifetime(lifetime), comma))
+ .map(|(life, comma)| Element::new(GenericParam::Lifetime(life), comma))
.chain(ty_params.unwrap_or_default()
.into_iter()
.map(Element::into_tuple)
- .map(|(ty_param, comma)| (GenericParam::Type(ty_param), comma)))
- .collect::<Vec<_>>()
- .into(),
+ .map(|(ty, comma)| Element::new(GenericParam::Type(ty), comma)))
+ .collect(),
gt_token: gt,
where_clause: None,
}
diff --git a/src/ty.rs b/src/ty.rs
index f7b9011..ab08230 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -152,10 +152,12 @@
T: Into<PathSegment>,
{
fn from(segment: T) -> Self {
- Path {
+ let mut path = Path {
leading_colon: None,
- segments: vec![(segment.into(), None)].into(),
- }
+ segments: Delimited::new(),
+ };
+ path.segments.push(segment.into());
+ path
}
}
@@ -550,14 +552,14 @@
impl TypePath {
named!(parse(allow_plus: bool) -> Self, do_parse!(
qpath: qpath >>
- parenthesized: cond!(
+ parenthesized: option!(cond_reduce!(
qpath.1.segments.last().unwrap().item().arguments.is_empty(),
- option!(syn!(ParenthesizedGenericArguments))
- ) >>
+ syn!(ParenthesizedGenericArguments)
+ )) >>
cond!(allow_plus, not!(punct!(+))) >>
({
let (qself, mut path) = qpath;
- if let Some(Some(parenthesized)) = parenthesized {
+ if let Some(parenthesized) = parenthesized {
let parenthesized = PathArguments::Parenthesized(parenthesized);
path.segments.last_mut().unwrap().item_mut().arguments = parenthesized;
}
@@ -580,12 +582,8 @@
let (pos, as_, path) = match path {
Some((as_, mut path)) => {
let pos = path.segments.len();
- if !path.segments.empty_or_trailing() {
- path.segments.push_trailing(colon2);
- }
- for item in rest {
- path.segments.push(item);
- }
+ path.segments.push_trailing(colon2);
+ path.segments.extend(rest);
(pos, Some(as_), path)
}
None => {
@@ -657,7 +655,11 @@
bounds: alt!(
cond_reduce!(allow_plus, Delimited::parse_terminated_nonempty)
|
- syn!(TypeParamBound) => { |x| vec![x].into() }
+ syn!(TypeParamBound) => {|x| {
+ let mut delimited = Delimited::new();
+ delimited.push(x);
+ delimited
+ }}
) >>
(TypeTraitObject {
dyn_token: dyn_token,
@@ -844,15 +846,14 @@
bound_lifetimes: option!(syn!(BoundLifetimes)) >>
trait_ref: syn!(Path) >>
parenthesized: option!(cond_reduce!(
- trait_ref.segments.get(trait_ref.segments.len() - 1).item().arguments.is_empty(),
+ trait_ref.segments.last().unwrap().item().arguments.is_empty(),
syn!(ParenthesizedGenericArguments)
)) >>
({
let mut trait_ref = trait_ref;
if let Some(parenthesized) = parenthesized {
let parenthesized = PathArguments::Parenthesized(parenthesized);
- let len = trait_ref.segments.len();
- trait_ref.segments.get_mut(len - 1).item_mut().arguments = parenthesized;
+ trait_ref.segments.last_mut().unwrap().item_mut().arguments = parenthesized;
}
PolyTraitRef {
bound_lifetimes: bound_lifetimes,