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 } }