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
use core::iter::FromIterator; pub trait Chain: Sized { type Item; type IntoIter: IntoIterator<Item=Self::Item>; fn into_iter_chain(self) -> <Self::IntoIter as IntoIterator>::IntoIter; fn collect<T: FromIterator<Self::Item>>(self) -> T { self.into_iter_chain().collect() } fn as_slice(&self) -> &[Self::Item]; } impl<T> Chain for Vec<T> { type Item = T; type IntoIter = <Self as IntoIterator>::IntoIter; fn into_iter_chain(self) -> <Self::IntoIter as IntoIterator>::IntoIter { IntoIterator::into_iter(self) } fn as_slice(&self) -> &[Self::Item] { &self } } pub struct Single<T>([T; 1]); impl<T> From<T> for Single<T> { fn from(item: T) -> Self { Self([item]) } } impl<T> IntoIterator for Single<T> { type Item = T; type IntoIter = SingleIter<T>; fn into_iter(self) -> Self::IntoIter { let [inner] = self.0; SingleIter(Some(inner)) } } impl<T> Chain for Single<T> { type Item = T; type IntoIter = <Self as IntoIterator>::IntoIter; fn into_iter_chain(self) -> <Self::IntoIter as IntoIterator>::IntoIter { IntoIterator::into_iter(self) } fn as_slice(&self) -> &[Self::Item] { &self.0 } } pub struct SingleIter<T>(Option<T>); impl<T> Iterator for SingleIter<T> { type Item = T; fn next(&mut self) -> Option<Self::Item> { self.0.take() } } pub trait IntoChain { type Item; type Chain: Chain<Item=Self::Item>; fn into_chain(self) -> Self::Chain; } impl<U: Chain> IntoChain for U { type Item = U::Item; type Chain = Self; fn into_chain(self) -> Self::Chain { self } } impl<T> IntoChain for Option<T> { type Item = T; type Chain = OptionChain<T>; fn into_chain(self) -> Self::Chain { OptionChain(self.map(|item| [item])) } } pub struct OptionChain<T>(Option<[T; 1]>); impl<T> Chain for OptionChain<T> { type Item = T; type IntoIter = <Self as IntoIterator>::IntoIter; fn into_iter_chain(self) -> <Self::IntoIter as IntoIterator>::IntoIter { IntoIterator::into_iter(self) } fn as_slice(&self) -> &[Self::Item] { self.0.as_ref().map(|arr| arr.as_ref()).unwrap_or(&[]) } } impl<T> IntoIterator for OptionChain<T> { type Item = T; type IntoIter = SingleIter<T>; fn into_iter(self) -> Self::IntoIter { self.0.map(|[inner]| { SingleIter(Some(inner)) }).unwrap_or_else(|| SingleIter(None)) } }