Guest User

Untitled

a guest
Nov 21st, 2018
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.88 KB | None | 0 0
  1. use std::iter::Peekable;
  2.  
  3. struct Join<T, S> {
  4. container: T,
  5. separator: S,
  6. }
  7.  
  8. pub struct JoinIter<Iter: Iterator, Sep> {
  9. iter: Peekable<Iter>,
  10. sep: Sep,
  11. next_sep: bool,
  12. }
  13.  
  14. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
  15. pub enum JoinItem<T, S> {
  16. Element(T),
  17. Separator(S),
  18. }
  19.  
  20. impl<T: IntoIterator, S: Clone> IntoIterator for Join<T, S> {
  21. type IntoIter = JoinIter<T::IntoIter, S>;
  22. type Item = JoinItem<T::Item, S>;
  23.  
  24. fn into_iter(self) -> Self::IntoIter {
  25. JoinIter::new(self.container.into_iter(), self.separator)
  26. }
  27. }
  28.  
  29. impl<'a, T, S> IntoIterator for &'a Join<T, S>
  30. where &'a T: IntoIterator
  31. {
  32. type IntoIter = JoinIter<<&'a T as IntoIterator>::IntoIter, &'a S>;
  33. type Item = JoinItem<<&'a T as IntoIterator>::Item, &'a S>;
  34.  
  35. fn into_iter(self) -> Self::IntoIter {
  36. JoinIter::new(self.container.into_iter(), &self.separator)
  37. }
  38. }
  39.  
  40. impl<T, S> Join<T, S>
  41. where for<'a> &'a T: IntoIterator
  42. {
  43. fn iter(&self) -> JoinIter<<&T as IntoIterator>::IntoIter, &S> {
  44. self.into_iter()
  45. }
  46. }
  47.  
  48. impl<I: Iterator, S: Clone> Iterator for JoinIter<I, S> {
  49. type Item = JoinItem<I::Item, S>;
  50.  
  51. /// Advance to the next item in the Join. This will either be the next
  52. /// element in the underlying iterator, or a clone of the separator.
  53. fn next(&mut self) -> Option<Self::Item> {
  54. let sep = &self.sep;
  55. let next_sep = &mut self.next_sep;
  56.  
  57. if *next_sep {
  58. self.iter.peek().map(|_| {
  59. *next_sep = false;
  60. JoinItem::Separator(sep.clone())
  61. })
  62. } else {
  63. self.iter.next().map(|element| {
  64. *next_sep = true;
  65. JoinItem::Element(element)
  66. })
  67. }
  68. }
  69. }
  70.  
  71. fn main() {
  72. // Create a join struct
  73. let join = vec![1, 2, 3].join_with(", ");
  74.  
  75. // This line fails to compile
  76. let iter = join.iter();
  77. }
Add Comment
Please, Sign In to add comment