syn_ext/
punctuated.rs

1use syn::punctuated::{Pair, Punctuated};
2
3/// Extension for [syn::punctuated::Punctuated]
4pub trait PunctuatedExt<T, P> {
5    /// Removes and returns the element at position index, popping all elements after it and push them back.
6    fn remove(&mut self, index: usize) -> Pair<T, P>
7    where
8        P: Default;
9}
10
11impl<T, P> PunctuatedExt<T, P> for Punctuated<T, P> {
12    fn remove(&mut self, index: usize) -> Pair<T, P>
13    where
14        P: Default,
15    {
16        let mut stack = Vec::new();
17        for _ in index + 1..self.len() {
18            stack.push(self.pop().unwrap().into_value());
19        }
20        let removed = self.pop().unwrap();
21        while let Some(item) = stack.pop() {
22            self.push(item)
23        }
24        removed
25    }
26}
27
28#[cfg(test)]
29#[cfg(all(feature = "parsing", feature = "derive"))]
30mod test {
31    use super::*;
32    use crate::assert_quote_eq;
33    use crate::meta::MetaList1;
34    use syn::parse_quote;
35
36    #[test]
37    fn test_remove() {
38        let mut list: MetaList1 = parse_quote!(meta(a, b, c, d));
39        list.nested.remove(2);
40        let expected: MetaList1 = parse_quote!(meta(a, b, d));
41        assert_quote_eq!(list, expected);
42        list.nested.remove(0);
43        let expected: MetaList1 = parse_quote!(meta(b, d));
44        assert_quote_eq!(list, expected);
45    }
46}