Polish Punctuated api
diff --git a/src/attr.rs b/src/attr.rs
index 5cb0fd0..96d96e5 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -188,9 +188,9 @@
None => return None,
};
if let Some(comma) = prev_comma {
- nested_meta_items.push_trailing(comma);
+ nested_meta_items.push_punct(comma);
}
- nested_meta_items.push(nested);
+ nested_meta_items.push_item(nested);
tts = rest;
}
diff --git a/src/expr.rs b/src/expr.rs
index 3cf9fa6..bf4bdb8 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -2677,7 +2677,7 @@
self.elems.to_tokens(tokens);
// If we only have one argument, we need a trailing comma to
// distinguish ExprTuple from ExprParen.
- if self.elems.len() == 1 && !self.elems.trailing_delim() {
+ if self.elems.len() == 1 && !self.elems.trailing_punct() {
<Token![,]>::default().to_tokens(tokens);
}
})
diff --git a/src/punctuated.rs b/src/punctuated.rs
index e8e6bd7..dc8c4ea 100644
--- a/src/punctuated.rs
+++ b/src/punctuated.rs
@@ -52,6 +52,12 @@
}
}
+ pub fn iter_mut(&mut self) -> IterMut<T, P> {
+ IterMut {
+ inner: self.inner.iter_mut(),
+ }
+ }
+
pub fn elements(&self) -> Elements<T, P> {
Elements {
inner: self.inner.iter(),
@@ -70,12 +76,12 @@
}
}
- pub fn push(&mut self, token: T) {
+ pub fn push_item(&mut self, item: T) {
assert!(self.empty_or_trailing());
- self.inner.push((token, None));
+ self.inner.push((item, None));
}
- pub fn push_trailing(&mut self, punctuation: P) {
+ pub fn push_punct(&mut self, punctuation: P) {
assert!(!self.is_empty());
let last = self.inner.last_mut().unwrap();
assert!(last.1.is_none());
@@ -86,19 +92,31 @@
self.inner.pop().map(|(t, d)| Element::new(t, d))
}
- pub fn trailing_delim(&self) -> bool {
+ pub fn trailing_punct(&self) -> bool {
self.inner.last().map(|last| last.1.is_some()).unwrap_or(false)
}
/// Returns true if either this `Punctuated` is empty, or it has a trailing
/// punctuation.
///
- /// Equivalent to `punctuated.is_empty() || punctuated.trailing_delim()`.
+ /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`.
pub fn empty_or_trailing(&self) -> bool {
self.inner.last().map(|last| last.1.is_some()).unwrap_or(true)
}
}
+impl<T, P> Punctuated<T, P>
+where
+ P: Default,
+{
+ pub fn push(&mut self, item: T) {
+ if !self.empty_or_trailing() {
+ self.push_punct(Default::default());
+ }
+ self.push_item(item);
+ }
+}
+
#[cfg(feature = "extra-traits")]
impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -145,6 +163,15 @@
}
}
+impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
+ type Item = &'a mut T;
+ type IntoIter = IterMut<'a, T, P>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ Punctuated::iter_mut(self)
+ }
+}
+
impl<T, P> Default for Punctuated<T, P> {
fn default() -> Self {
Punctuated::new()
@@ -220,6 +247,18 @@
}
}
+pub struct IterMut<'a, T: 'a, P: 'a> {
+ inner: slice::IterMut<'a, (T, Option<P>)>,
+}
+
+impl<'a, T, P> Iterator for IterMut<'a, T, P> {
+ type Item = &'a mut T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.next().map(|pair| &mut pair.0)
+ }
+}
+
pub enum Element<T, P> {
Punctuated(T, P),
End(T),
@@ -349,7 +388,7 @@
return parse_error();
}
input = i;
- res.push(o);
+ res.push_item(o);
// get the separator first
while let Ok((s, i2)) = P::parse(input) {
@@ -362,8 +401,8 @@
if i3 == i2 {
break;
}
- res.push_trailing(s);
- res.push(o3);
+ res.push_punct(s);
+ res.push_item(o3);
input = i3;
} else {
break;
@@ -371,7 +410,7 @@
}
if terminated {
if let Ok((sep, after)) = P::parse(input) {
- res.push_trailing(sep);
+ res.push_punct(sep);
input = after;
}
}
@@ -393,7 +432,7 @@
P: ToTokens,
{
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append_all(self.iter())
+ tokens.append_all(self.elements())
}
}
diff --git a/src/ty.rs b/src/ty.rs
index b504b47..c8d7e87 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -156,7 +156,7 @@
leading_colon: None,
segments: Punctuated::new(),
};
- path.segments.push(segment.into());
+ path.segments.push_item(segment.into());
path
}
}
@@ -582,7 +582,7 @@
let (pos, as_, path) = match path {
Some((as_, mut path)) => {
let pos = path.segments.len();
- path.segments.push_trailing(colon2);
+ path.segments.push_punct(colon2);
path.segments.extend(rest.into_elements());
(pos, Some(as_), path)
}
@@ -657,7 +657,7 @@
|
syn!(TypeParamBound) => {|x| {
let mut bounds = Punctuated::new();
- bounds.push(x);
+ bounds.push_item(x);
bounds
}}
) >>