1 //! A punctuated sequence of syntax tree nodes separated by punctuation. 2 //! 3 //! Lots of things in Rust are punctuated sequences. 4 //! 5 //! - The fields of a struct are `Punctuated<Field, Token![,]>`. 6 //! - The segments of a path are `Punctuated<PathSegment, Token![::]>`. 7 //! - The bounds on a generic parameter are `Punctuated<TypeParamBound, 8 //! Token![+]>`. 9 //! - The arguments to a function call are `Punctuated<Expr, Token![,]>`. 10 //! 11 //! This module provides a common representation for these punctuated sequences 12 //! in the form of the [`Punctuated<T, P>`] type. We store a vector of pairs of 13 //! syntax tree node + punctuation, where every node in the sequence is followed 14 //! by punctuation except for possibly the final one. 15 //! 16 //! [`Punctuated<T, P>`]: struct.Punctuated.html 17 //! 18 //! ```text 19 //! a_function_call(arg1, arg2, arg3); 20 //! ^^^^^ ~~~~~ ^^^^ 21 //! ``` 22 23 #[cfg(feature = "extra-traits")] 24 use std::fmt::{self, Debug}; 25 #[cfg(any(feature = "full", feature = "derive"))] 26 use std::iter; 27 use std::iter::FromIterator; 28 use std::marker::PhantomData; 29 use std::ops::{Index, IndexMut}; 30 use std::option; 31 use std::slice; 32 use std::vec; 33 34 #[cfg(feature = "parsing")] 35 use parse::{Parse, ParseStream, Result}; 36 #[cfg(any(feature = "full", feature = "derive"))] 37 use private; 38 #[cfg(feature = "parsing")] 39 use token::Token; 40 41 /// A punctuated sequence of syntax tree nodes of type `T` separated by 42 /// punctuation of type `P`. 43 /// 44 /// Refer to the [module documentation] for details about punctuated sequences. 45 /// 46 /// [module documentation]: self 47 #[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash))] 48 #[cfg_attr(feature = "clone-impls", derive(Clone))] 49 pub struct Punctuated<T, P> { 50 inner: Vec<(T, P)>, 51 last: Option<Box<T>>, 52 } 53 54 impl<T, P> Punctuated<T, P> { 55 /// Creates an empty punctuated sequence. new() -> Punctuated<T, P>56 pub fn new() -> Punctuated<T, P> { 57 Punctuated { 58 inner: Vec::new(), 59 last: None, 60 } 61 } 62 63 /// Determines whether this punctuated sequence is empty, meaning it 64 /// contains no syntax tree nodes or punctuation. is_empty(&self) -> bool65 pub fn is_empty(&self) -> bool { 66 self.inner.len() == 0 && self.last.is_none() 67 } 68 69 /// Returns the number of syntax tree nodes in this punctuated sequence. 70 /// 71 /// This is the number of nodes of type `T`, not counting the punctuation of 72 /// type `P`. len(&self) -> usize73 pub fn len(&self) -> usize { 74 self.inner.len() + if self.last.is_some() { 1 } else { 0 } 75 } 76 77 /// Borrows the first punctuated pair in this sequence. first(&self) -> Option<Pair<&T, &P>>78 pub fn first(&self) -> Option<Pair<&T, &P>> { 79 self.pairs().next() 80 } 81 82 /// Borrows the last punctuated pair in this sequence. last(&self) -> Option<Pair<&T, &P>>83 pub fn last(&self) -> Option<Pair<&T, &P>> { 84 if self.last.is_some() { 85 self.last.as_ref().map(|t| Pair::End(t.as_ref())) 86 } else { 87 self.inner 88 .last() 89 .map(|&(ref t, ref d)| Pair::Punctuated(t, d)) 90 } 91 } 92 93 /// Mutably borrows the last punctuated pair in this sequence. last_mut(&mut self) -> Option<Pair<&mut T, &mut P>>94 pub fn last_mut(&mut self) -> Option<Pair<&mut T, &mut P>> { 95 if self.last.is_some() { 96 self.last.as_mut().map(|t| Pair::End(t.as_mut())) 97 } else { 98 self.inner 99 .last_mut() 100 .map(|&mut (ref mut t, ref mut d)| Pair::Punctuated(t, d)) 101 } 102 } 103 104 /// Returns an iterator over borrowed syntax tree nodes of type `&T`. iter(&self) -> Iter<T>105 pub fn iter(&self) -> Iter<T> { 106 Iter { 107 inner: Box::new(PrivateIter { 108 inner: self.inner.iter(), 109 last: self.last.as_ref().map(Box::as_ref).into_iter(), 110 }), 111 } 112 } 113 114 /// Returns an iterator over mutably borrowed syntax tree nodes of type 115 /// `&mut T`. iter_mut(&mut self) -> IterMut<T>116 pub fn iter_mut(&mut self) -> IterMut<T> { 117 IterMut { 118 inner: Box::new(PrivateIterMut { 119 inner: self.inner.iter_mut(), 120 last: self.last.as_mut().map(Box::as_mut).into_iter(), 121 }), 122 } 123 } 124 125 /// Returns an iterator over the contents of this sequence as borrowed 126 /// punctuated pairs. pairs(&self) -> Pairs<T, P>127 pub fn pairs(&self) -> Pairs<T, P> { 128 Pairs { 129 inner: self.inner.iter(), 130 last: self.last.as_ref().map(Box::as_ref).into_iter(), 131 } 132 } 133 134 /// Returns an iterator over the contents of this sequence as mutably 135 /// borrowed punctuated pairs. pairs_mut(&mut self) -> PairsMut<T, P>136 pub fn pairs_mut(&mut self) -> PairsMut<T, P> { 137 PairsMut { 138 inner: self.inner.iter_mut(), 139 last: self.last.as_mut().map(Box::as_mut).into_iter(), 140 } 141 } 142 143 /// Returns an iterator over the contents of this sequence as owned 144 /// punctuated pairs. into_pairs(self) -> IntoPairs<T, P>145 pub fn into_pairs(self) -> IntoPairs<T, P> { 146 IntoPairs { 147 inner: self.inner.into_iter(), 148 last: self.last.map(|t| *t).into_iter(), 149 } 150 } 151 152 /// Appends a syntax tree node onto the end of this punctuated sequence. The 153 /// sequence must previously have a trailing punctuation. 154 /// 155 /// Use [`push`] instead if the punctuated sequence may or may not already 156 /// have trailing punctuation. 157 /// 158 /// [`push`]: Punctuated::push 159 /// 160 /// # Panics 161 /// 162 /// Panics if the sequence does not already have a trailing punctuation when 163 /// this method is called. push_value(&mut self, value: T)164 pub fn push_value(&mut self, value: T) { 165 assert!(self.empty_or_trailing()); 166 self.last = Some(Box::new(value)); 167 } 168 169 /// Appends a trailing punctuation onto the end of this punctuated sequence. 170 /// The sequence must be non-empty and must not already have trailing 171 /// punctuation. 172 /// 173 /// # Panics 174 /// 175 /// Panics if the sequence is empty or already has a trailing punctuation. push_punct(&mut self, punctuation: P)176 pub fn push_punct(&mut self, punctuation: P) { 177 assert!(self.last.is_some()); 178 let last = self.last.take().unwrap(); 179 self.inner.push((*last, punctuation)); 180 } 181 182 /// Removes the last punctuated pair from this sequence, or `None` if the 183 /// sequence is empty. pop(&mut self) -> Option<Pair<T, P>>184 pub fn pop(&mut self) -> Option<Pair<T, P>> { 185 if self.last.is_some() { 186 self.last.take().map(|t| Pair::End(*t)) 187 } else { 188 self.inner.pop().map(|(t, d)| Pair::Punctuated(t, d)) 189 } 190 } 191 192 /// Determines whether this punctuated sequence ends with a trailing 193 /// punctuation. trailing_punct(&self) -> bool194 pub fn trailing_punct(&self) -> bool { 195 self.last.is_none() && !self.is_empty() 196 } 197 198 /// Returns true if either this `Punctuated` is empty, or it has a trailing 199 /// punctuation. 200 /// 201 /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`. empty_or_trailing(&self) -> bool202 pub fn empty_or_trailing(&self) -> bool { 203 self.last.is_none() 204 } 205 206 /// Appends a syntax tree node onto the end of this punctuated sequence. 207 /// 208 /// If there is not a trailing punctuation in this sequence when this method 209 /// is called, the default value of punctuation type `P` is inserted before 210 /// the given value of type `T`. push(&mut self, value: T) where P: Default,211 pub fn push(&mut self, value: T) 212 where 213 P: Default, 214 { 215 if !self.empty_or_trailing() { 216 self.push_punct(Default::default()); 217 } 218 self.push_value(value); 219 } 220 221 /// Inserts an element at position `index`. 222 /// 223 /// # Panics 224 /// 225 /// Panics if `index` is greater than the number of elements previously in 226 /// this punctuated sequence. insert(&mut self, index: usize, value: T) where P: Default,227 pub fn insert(&mut self, index: usize, value: T) 228 where 229 P: Default, 230 { 231 assert!(index <= self.len()); 232 233 if index == self.len() { 234 self.push(value); 235 } else { 236 self.inner.insert(index, (value, Default::default())); 237 } 238 } 239 240 /// Parses zero or more occurrences of `T` separated by punctuation of type 241 /// `P`, with optional trailing punctuation. 242 /// 243 /// Parsing continues until the end of this parse stream. The entire content 244 /// of this parse stream must consist of `T` and `P`. 245 /// 246 /// *This function is available if Syn is built with the `"parsing"` 247 /// feature.* 248 #[cfg(feature = "parsing")] parse_terminated(input: ParseStream) -> Result<Self> where T: Parse, P: Parse,249 pub fn parse_terminated(input: ParseStream) -> Result<Self> 250 where 251 T: Parse, 252 P: Parse, 253 { 254 Self::parse_terminated_with(input, T::parse) 255 } 256 257 /// Parses zero or more occurrences of `T` using the given parse function, 258 /// separated by punctuation of type `P`, with optional trailing 259 /// punctuation. 260 /// 261 /// Like [`parse_terminated`], the entire content of this stream is expected 262 /// to be parsed. 263 /// 264 /// [`parse_terminated`]: Punctuated::parse_terminated 265 /// 266 /// *This function is available if Syn is built with the `"parsing"` 267 /// feature.* 268 #[cfg(feature = "parsing")] parse_terminated_with( input: ParseStream, parser: fn(ParseStream) -> Result<T>, ) -> Result<Self> where P: Parse,269 pub fn parse_terminated_with( 270 input: ParseStream, 271 parser: fn(ParseStream) -> Result<T>, 272 ) -> Result<Self> 273 where 274 P: Parse, 275 { 276 let mut punctuated = Punctuated::new(); 277 278 loop { 279 if input.is_empty() { 280 break; 281 } 282 let value = parser(input)?; 283 punctuated.push_value(value); 284 if input.is_empty() { 285 break; 286 } 287 let punct = input.parse()?; 288 punctuated.push_punct(punct); 289 } 290 291 Ok(punctuated) 292 } 293 294 /// Parses one or more occurrences of `T` separated by punctuation of type 295 /// `P`, not accepting trailing punctuation. 296 /// 297 /// Parsing continues as long as punctuation `P` is present at the head of 298 /// the stream. This method returns upon parsing a `T` and observing that it 299 /// is not followed by a `P`, even if there are remaining tokens in the 300 /// stream. 301 /// 302 /// *This function is available if Syn is built with the `"parsing"` 303 /// feature.* 304 #[cfg(feature = "parsing")] parse_separated_nonempty(input: ParseStream) -> Result<Self> where T: Parse, P: Token + Parse,305 pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self> 306 where 307 T: Parse, 308 P: Token + Parse, 309 { 310 Self::parse_separated_nonempty_with(input, T::parse) 311 } 312 313 /// Parses one or more occurrences of `T` using the given parse function, 314 /// separated by punctuation of type `P`, not accepting trailing 315 /// punctuation. 316 /// 317 /// Like [`parse_separated_nonempty`], may complete early without parsing 318 /// the entire content of this stream. 319 /// 320 /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty 321 /// 322 /// *This function is available if Syn is built with the `"parsing"` 323 /// feature.* 324 #[cfg(feature = "parsing")] parse_separated_nonempty_with( input: ParseStream, parser: fn(ParseStream) -> Result<T>, ) -> Result<Self> where P: Token + Parse,325 pub fn parse_separated_nonempty_with( 326 input: ParseStream, 327 parser: fn(ParseStream) -> Result<T>, 328 ) -> Result<Self> 329 where 330 P: Token + Parse, 331 { 332 let mut punctuated = Punctuated::new(); 333 334 loop { 335 let value = parser(input)?; 336 punctuated.push_value(value); 337 if !P::peek(input.cursor()) { 338 break; 339 } 340 let punct = input.parse()?; 341 punctuated.push_punct(punct); 342 } 343 344 Ok(punctuated) 345 } 346 } 347 348 #[cfg(feature = "extra-traits")] 349 impl<T: Debug, P: Debug> Debug for Punctuated<T, P> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result350 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 351 let mut list = f.debug_list(); 352 for &(ref t, ref p) in &self.inner { 353 list.entry(t); 354 list.entry(p); 355 } 356 if let Some(ref last) = self.last { 357 list.entry(last); 358 } 359 list.finish() 360 } 361 } 362 363 impl<T, P> FromIterator<T> for Punctuated<T, P> 364 where 365 P: Default, 366 { from_iter<I: IntoIterator<Item = T>>(i: I) -> Self367 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self { 368 let mut ret = Punctuated::new(); 369 ret.extend(i); 370 ret 371 } 372 } 373 374 impl<T, P> Extend<T> for Punctuated<T, P> 375 where 376 P: Default, 377 { extend<I: IntoIterator<Item = T>>(&mut self, i: I)378 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) { 379 for value in i { 380 self.push(value); 381 } 382 } 383 } 384 385 impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> { from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self386 fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self { 387 let mut ret = Punctuated::new(); 388 ret.extend(i); 389 ret 390 } 391 } 392 393 impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> { extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I)394 fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) { 395 assert!(self.empty_or_trailing()); 396 let mut nomore = false; 397 for pair in i { 398 if nomore { 399 panic!("Punctuated extended with items after a Pair::End"); 400 } 401 match pair { 402 Pair::Punctuated(a, b) => self.inner.push((a, b)), 403 Pair::End(a) => { 404 self.last = Some(Box::new(a)); 405 nomore = true; 406 } 407 } 408 } 409 } 410 } 411 412 impl<T, P> IntoIterator for Punctuated<T, P> { 413 type Item = T; 414 type IntoIter = IntoIter<T, P>; 415 into_iter(self) -> Self::IntoIter416 fn into_iter(self) -> Self::IntoIter { 417 let mut elements = Vec::with_capacity(self.len()); 418 elements.extend(self.inner.into_iter().map(|pair| pair.0)); 419 elements.extend(self.last.map(|t| *t)); 420 421 IntoIter { 422 inner: elements.into_iter(), 423 marker: PhantomData, 424 } 425 } 426 } 427 428 impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> { 429 type Item = &'a T; 430 type IntoIter = Iter<'a, T>; 431 into_iter(self) -> Self::IntoIter432 fn into_iter(self) -> Self::IntoIter { 433 Punctuated::iter(self) 434 } 435 } 436 437 impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> { 438 type Item = &'a mut T; 439 type IntoIter = IterMut<'a, T>; 440 into_iter(self) -> Self::IntoIter441 fn into_iter(self) -> Self::IntoIter { 442 Punctuated::iter_mut(self) 443 } 444 } 445 446 impl<T, P> Default for Punctuated<T, P> { default() -> Self447 fn default() -> Self { 448 Punctuated::new() 449 } 450 } 451 452 /// An iterator over borrowed pairs of type `Pair<&T, &P>`. 453 /// 454 /// Refer to the [module documentation] for details about punctuated sequences. 455 /// 456 /// [module documentation]: self 457 pub struct Pairs<'a, T: 'a, P: 'a> { 458 inner: slice::Iter<'a, (T, P)>, 459 last: option::IntoIter<&'a T>, 460 } 461 462 impl<'a, T, P> Iterator for Pairs<'a, T, P> { 463 type Item = Pair<&'a T, &'a P>; 464 next(&mut self) -> Option<Self::Item>465 fn next(&mut self) -> Option<Self::Item> { 466 self.inner 467 .next() 468 .map(|&(ref t, ref p)| Pair::Punctuated(t, p)) 469 .or_else(|| self.last.next().map(Pair::End)) 470 } 471 } 472 473 impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> { len(&self) -> usize474 fn len(&self) -> usize { 475 self.inner.len() + self.last.len() 476 } 477 } 478 479 // No Clone bound on T or P. 480 impl<'a, T, P> Clone for Pairs<'a, T, P> { clone(&self) -> Self481 fn clone(&self) -> Self { 482 Pairs { 483 inner: self.inner.clone(), 484 last: self.last.clone(), 485 } 486 } 487 } 488 489 /// An iterator over mutably borrowed pairs of type `Pair<&mut T, &mut P>`. 490 /// 491 /// Refer to the [module documentation] for details about punctuated sequences. 492 /// 493 /// [module documentation]: self 494 pub struct PairsMut<'a, T: 'a, P: 'a> { 495 inner: slice::IterMut<'a, (T, P)>, 496 last: option::IntoIter<&'a mut T>, 497 } 498 499 impl<'a, T, P> Iterator for PairsMut<'a, T, P> { 500 type Item = Pair<&'a mut T, &'a mut P>; 501 next(&mut self) -> Option<Self::Item>502 fn next(&mut self) -> Option<Self::Item> { 503 self.inner 504 .next() 505 .map(|&mut (ref mut t, ref mut p)| Pair::Punctuated(t, p)) 506 .or_else(|| self.last.next().map(Pair::End)) 507 } 508 } 509 510 impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> { len(&self) -> usize511 fn len(&self) -> usize { 512 self.inner.len() + self.last.len() 513 } 514 } 515 516 /// An iterator over owned pairs of type `Pair<T, P>`. 517 /// 518 /// Refer to the [module documentation] for details about punctuated sequences. 519 /// 520 /// [module documentation]: self 521 #[derive(Clone)] 522 pub struct IntoPairs<T, P> { 523 inner: vec::IntoIter<(T, P)>, 524 last: option::IntoIter<T>, 525 } 526 527 impl<T, P> Iterator for IntoPairs<T, P> { 528 type Item = Pair<T, P>; 529 next(&mut self) -> Option<Self::Item>530 fn next(&mut self) -> Option<Self::Item> { 531 self.inner 532 .next() 533 .map(|(t, p)| Pair::Punctuated(t, p)) 534 .or_else(|| self.last.next().map(Pair::End)) 535 } 536 } 537 538 impl<T, P> ExactSizeIterator for IntoPairs<T, P> { len(&self) -> usize539 fn len(&self) -> usize { 540 self.inner.len() + self.last.len() 541 } 542 } 543 544 /// An iterator over owned values of type `T`. 545 /// 546 /// Refer to the [module documentation] for details about punctuated sequences. 547 /// 548 /// [module documentation]: self 549 #[derive(Clone)] 550 pub struct IntoIter<T, P> { 551 inner: vec::IntoIter<T>, 552 553 // TODO: remove P type parameter in the next breaking change 554 marker: PhantomData<P>, 555 } 556 557 impl<T, P> Iterator for IntoIter<T, P> { 558 type Item = T; 559 next(&mut self) -> Option<Self::Item>560 fn next(&mut self) -> Option<Self::Item> { 561 self.inner.next() 562 } 563 } 564 565 impl<T, P> ExactSizeIterator for IntoIter<T, P> { len(&self) -> usize566 fn len(&self) -> usize { 567 self.inner.len() 568 } 569 } 570 571 /// An iterator over borrowed values of type `&T`. 572 /// 573 /// Refer to the [module documentation] for details about punctuated sequences. 574 /// 575 /// [module documentation]: self 576 pub struct Iter<'a, T: 'a> { 577 // The `Item = &'a T` needs to be specified to support rustc 1.31 and older. 578 // On modern compilers we would be able to write just IterTrait<'a, T> where 579 // Item can be inferred unambiguously from the supertrait. 580 inner: Box<IterTrait<'a, T, Item = &'a T> + 'a>, 581 } 582 583 trait IterTrait<'a, T: 'a>: ExactSizeIterator<Item = &'a T> { clone_box(&self) -> Box<IterTrait<'a, T, Item = &'a T> + 'a>584 fn clone_box(&self) -> Box<IterTrait<'a, T, Item = &'a T> + 'a>; 585 } 586 587 struct PrivateIter<'a, T: 'a, P: 'a> { 588 inner: slice::Iter<'a, (T, P)>, 589 last: option::IntoIter<&'a T>, 590 } 591 592 #[cfg(any(feature = "full", feature = "derive"))] 593 impl private { empty_punctuated_iter<'a, T>() -> Iter<'a, T>594 pub fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> { 595 Iter { 596 inner: Box::new(iter::empty()), 597 } 598 } 599 } 600 601 // No Clone bound on T. 602 impl<'a, T> Clone for Iter<'a, T> { clone(&self) -> Self603 fn clone(&self) -> Self { 604 Iter { 605 inner: self.inner.clone_box(), 606 } 607 } 608 } 609 610 impl<'a, T> Iterator for Iter<'a, T> { 611 type Item = &'a T; 612 next(&mut self) -> Option<Self::Item>613 fn next(&mut self) -> Option<Self::Item> { 614 self.inner.next() 615 } 616 } 617 618 impl<'a, T> ExactSizeIterator for Iter<'a, T> { len(&self) -> usize619 fn len(&self) -> usize { 620 self.inner.len() 621 } 622 } 623 624 impl<'a, T, P> Iterator for PrivateIter<'a, T, P> { 625 type Item = &'a T; 626 next(&mut self) -> Option<Self::Item>627 fn next(&mut self) -> Option<Self::Item> { 628 self.inner 629 .next() 630 .map(|pair| &pair.0) 631 .or_else(|| self.last.next()) 632 } 633 } 634 635 impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> { len(&self) -> usize636 fn len(&self) -> usize { 637 self.inner.len() + self.last.len() 638 } 639 } 640 641 // No Clone bound on T or P. 642 impl<'a, T, P> Clone for PrivateIter<'a, T, P> { clone(&self) -> Self643 fn clone(&self) -> Self { 644 PrivateIter { 645 inner: self.inner.clone(), 646 last: self.last.clone(), 647 } 648 } 649 } 650 651 impl<'a, T: 'a, I: 'a> IterTrait<'a, T> for I 652 where 653 I: ExactSizeIterator<Item = &'a T> + Clone, 654 { clone_box(&self) -> Box<IterTrait<'a, T, Item = &'a T> + 'a>655 fn clone_box(&self) -> Box<IterTrait<'a, T, Item = &'a T> + 'a> { 656 Box::new(self.clone()) 657 } 658 } 659 660 /// An iterator over mutably borrowed values of type `&mut T`. 661 /// 662 /// Refer to the [module documentation] for details about punctuated sequences. 663 /// 664 /// [module documentation]: self 665 pub struct IterMut<'a, T: 'a> { 666 inner: Box<ExactSizeIterator<Item = &'a mut T> + 'a>, 667 } 668 669 struct PrivateIterMut<'a, T: 'a, P: 'a> { 670 inner: slice::IterMut<'a, (T, P)>, 671 last: option::IntoIter<&'a mut T>, 672 } 673 674 #[cfg(any(feature = "full", feature = "derive"))] 675 impl private { empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T>676 pub fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> { 677 IterMut { 678 inner: Box::new(iter::empty()), 679 } 680 } 681 } 682 683 impl<'a, T> Iterator for IterMut<'a, T> { 684 type Item = &'a mut T; 685 next(&mut self) -> Option<Self::Item>686 fn next(&mut self) -> Option<Self::Item> { 687 self.inner.next() 688 } 689 } 690 691 impl<'a, T> ExactSizeIterator for IterMut<'a, T> { len(&self) -> usize692 fn len(&self) -> usize { 693 self.inner.len() 694 } 695 } 696 697 impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> { 698 type Item = &'a mut T; 699 next(&mut self) -> Option<Self::Item>700 fn next(&mut self) -> Option<Self::Item> { 701 self.inner 702 .next() 703 .map(|pair| &mut pair.0) 704 .or_else(|| self.last.next()) 705 } 706 } 707 708 impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> { len(&self) -> usize709 fn len(&self) -> usize { 710 self.inner.len() + self.last.len() 711 } 712 } 713 714 /// A single syntax tree node of type `T` followed by its trailing punctuation 715 /// of type `P` if any. 716 /// 717 /// Refer to the [module documentation] for details about punctuated sequences. 718 /// 719 /// [module documentation]: self 720 #[cfg_attr(feature = "clone-impls", derive(Clone))] 721 pub enum Pair<T, P> { 722 Punctuated(T, P), 723 End(T), 724 } 725 726 impl<T, P> Pair<T, P> { 727 /// Extracts the syntax tree node from this punctuated pair, discarding the 728 /// following punctuation. into_value(self) -> T729 pub fn into_value(self) -> T { 730 match self { 731 Pair::Punctuated(t, _) | Pair::End(t) => t, 732 } 733 } 734 735 /// Borrows the syntax tree node from this punctuated pair. value(&self) -> &T736 pub fn value(&self) -> &T { 737 match *self { 738 Pair::Punctuated(ref t, _) | Pair::End(ref t) => t, 739 } 740 } 741 742 /// Mutably borrows the syntax tree node from this punctuated pair. value_mut(&mut self) -> &mut T743 pub fn value_mut(&mut self) -> &mut T { 744 match *self { 745 Pair::Punctuated(ref mut t, _) | Pair::End(ref mut t) => t, 746 } 747 } 748 749 /// Borrows the punctuation from this punctuated pair, unless this pair is 750 /// the final one and there is no trailing punctuation. punct(&self) -> Option<&P>751 pub fn punct(&self) -> Option<&P> { 752 match *self { 753 Pair::Punctuated(_, ref d) => Some(d), 754 Pair::End(_) => None, 755 } 756 } 757 758 /// Creates a punctuated pair out of a syntax tree node and an optional 759 /// following punctuation. new(t: T, d: Option<P>) -> Self760 pub fn new(t: T, d: Option<P>) -> Self { 761 match d { 762 Some(d) => Pair::Punctuated(t, d), 763 None => Pair::End(t), 764 } 765 } 766 767 /// Produces this punctuated pair as a tuple of syntax tree node and 768 /// optional following punctuation. into_tuple(self) -> (T, Option<P>)769 pub fn into_tuple(self) -> (T, Option<P>) { 770 match self { 771 Pair::Punctuated(t, d) => (t, Some(d)), 772 Pair::End(t) => (t, None), 773 } 774 } 775 } 776 777 impl<T, P> Index<usize> for Punctuated<T, P> { 778 type Output = T; 779 index(&self, index: usize) -> &Self::Output780 fn index(&self, index: usize) -> &Self::Output { 781 if index == self.len() - 1 { 782 match self.last { 783 Some(ref t) => t, 784 None => &self.inner[index].0, 785 } 786 } else { 787 &self.inner[index].0 788 } 789 } 790 } 791 792 impl<T, P> IndexMut<usize> for Punctuated<T, P> { index_mut(&mut self, index: usize) -> &mut Self::Output793 fn index_mut(&mut self, index: usize) -> &mut Self::Output { 794 if index == self.len() - 1 { 795 match self.last { 796 Some(ref mut t) => t, 797 None => &mut self.inner[index].0, 798 } 799 } else { 800 &mut self.inner[index].0 801 } 802 } 803 } 804 805 #[cfg(feature = "printing")] 806 mod printing { 807 use super::*; 808 use proc_macro2::TokenStream; 809 use quote::{ToTokens, TokenStreamExt}; 810 811 impl<T, P> ToTokens for Punctuated<T, P> 812 where 813 T: ToTokens, 814 P: ToTokens, 815 { to_tokens(&self, tokens: &mut TokenStream)816 fn to_tokens(&self, tokens: &mut TokenStream) { 817 tokens.append_all(self.pairs()) 818 } 819 } 820 821 impl<T, P> ToTokens for Pair<T, P> 822 where 823 T: ToTokens, 824 P: ToTokens, 825 { to_tokens(&self, tokens: &mut TokenStream)826 fn to_tokens(&self, tokens: &mut TokenStream) { 827 match *self { 828 Pair::Punctuated(ref a, ref b) => { 829 a.to_tokens(tokens); 830 b.to_tokens(tokens); 831 } 832 Pair::End(ref a) => a.to_tokens(tokens), 833 } 834 } 835 } 836 } 837