1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
use std::cell::RefCell;

/// A hack utility struct to wrap use-once iterators.
///
/// # Clone semantics
/// Every time CloneOnce is cloned, the underlying iterator is moved to the CloneOnce returned by
/// the `clone` method, and the original CloneOnce will panick if it is iterated over.
/// This behaviour would result in `serde_iter` consuming the underlying iterator exactly once if
/// it is only serialized exactly once.
///
/// # Usage
/// Wrap your iterator with this struct if you are **very sure** that it will only be serialized
/// once. This hack is necessary if your iterator does not implement `Clone`.
///
/// # Example
/// ```
/// #[derive(serde::Serialize)]
/// struct Foo<I>
/// where
///     I: Iterator<Item = u32> + Clone,
/// {
///     #[serde(with = "serde_iter::seq")]
///     bar: I,
/// }
///
/// let mut v = vec![1, 2, 3];
/// let drain = v.drain(..);
/// let foo = Foo {
///     bar: serde_iter::CloneOnce::from(drain),
/// };
///
/// assert_eq!(serde_json::to_value(&foo).unwrap(), serde_json::json!({
///     "bar": [1, 2, 3]
/// }));
/// ```
///
/// If this struct is serialized again, it panicks:
/// ```should_panic
/// #[derive(serde::Serialize)]
/// struct Foo<I>
/// where
///     I: Iterator<Item = u32> + Clone,
/// {
///     #[serde(with = "serde_iter::seq")]
///     bar: I,
/// }
///
/// let mut v = vec![1, 2, 3];
/// let drain = v.drain(..);
/// let foo = Foo {
///     bar: serde_iter::CloneOnce::from(drain),
/// };
///
/// assert_eq!(serde_json::to_value(&foo).unwrap(), serde_json::json!({
///     "bar": [1, 2, 3]
/// }));
/// serde_json::to_value(&foo).ok();
/// ```
pub struct CloneOnce<T, I>(RefCell<Option<I>>)
where
    I: Iterator<Item = T>;

/// Converts a (non-Clone) iterator into a CloneOnce iterator.
impl<T, I> From<I> for CloneOnce<T, I>
where
    I: Iterator<Item = T>,
{
    fn from(iter: I) -> Self {
        Self(RefCell::new(Some(iter)))
    }
}

/// Moves the underlying iterator to a cloned value, and leaves a panicking iterator.
impl<T, I> Clone for CloneOnce<T, I>
where
    I: Iterator<Item = T>,
{
    #[inline]
    fn clone(&self) -> Self {
        let mut borrow = self.0.borrow_mut();
        let oi = borrow.take();
        if oi.is_none() {
            panic!("Attempt to clone a CloneOnce twice");
        }
        drop(borrow);

        Self(RefCell::new(oi))
    }
}

impl<T, I> Iterator for CloneOnce<T, I>
where
    I: Iterator<Item = T>,
{
    type Item = T;

    fn next(&mut self) -> Option<T> {
        let borrow = self.0.get_mut();
        let option = borrow.as_mut();
        let iter = option.expect("Attempt to iterate over a CloneOnce");
        let ret = iter.next();
        drop(borrow);

        ret
    }
}