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 107 108 109 110 111 112 113 114 115 116 117 118 119
use serde::{Deserialize, Serialize}; use std::{any::type_name, error, fmt, io, marker::PhantomData, sync::Arc}; use crate::dist_iter::{Consumer, DistributedIterator}; pub struct ResultExpand<T, E>(pub Result<T, E>); impl<T, E> IntoIterator for ResultExpand<T, E> where T: IntoIterator, { type Item = Result<T::Item, E>; type IntoIter = ResultExpandIter<T::IntoIter, E>; fn into_iter(self) -> Self::IntoIter { ResultExpandIter(self.0.map(IntoIterator::into_iter).map_err(Some)) } } pub struct ResultExpandIter<T, E>(Result<T, Option<E>>); impl<T, E> Iterator for ResultExpandIter<T, E> where T: Iterator, { type Item = Result<T::Item, E>; fn next(&mut self) -> Option<Self::Item> { transpose(self.0.as_mut().map(Iterator::next).map_err(Option::take)) } } fn transpose<T, E>(result: Result<Option<T>, Option<E>>) -> Option<Result<T, E>> { match result { Ok(Some(x)) => Some(Ok(x)), Err(Some(e)) => Some(Err(e)), Ok(None) | Err(None) => None, } } #[derive(Clone, Serialize, Deserialize)] #[serde(transparent)] pub struct IoError(#[serde(with = "crate::misc_serde")] Arc<io::Error>); impl PartialEq for IoError { fn eq(&self, other: &Self) -> bool { self.0.to_string() == other.0.to_string() } } impl error::Error for IoError {} impl fmt::Display for IoError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) } } impl fmt::Debug for IoError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&self.0, f) } } impl From<io::Error> for IoError { fn from(err: io::Error) -> Self { Self(Arc::new(err)) } } impl From<IoError> for io::Error { fn from(err: IoError) -> Self { Arc::try_unwrap(err.0).unwrap() } } pub struct ImplDistributedIterator<T>(PhantomData<fn(T)>); impl<T> ImplDistributedIterator<T> { pub fn new<U>(_drop: U) -> Self where U: DistributedIterator<Item = T>, { Self(PhantomData) } } impl<T: 'static> DistributedIterator for ImplDistributedIterator<T> { type Item = T; type Task = ImplConsumer<T>; fn size_hint(&self) -> (usize, Option<usize>) { unreachable!() } fn next_task(&mut self) -> Option<Self::Task> { unreachable!() } } #[derive(Serialize, Deserialize)] pub struct ImplConsumer<T>(PhantomData<fn(T)>); impl<T: 'static> Consumer for ImplConsumer<T> { type Item = T; fn run(self, _i: &mut impl FnMut(Self::Item) -> bool) -> bool { unreachable!() } } pub fn type_coerce<A, B>(a: A) -> B { try_type_coerce(a) .unwrap_or_else(|| panic!("can't coerce {} to {}", type_name::<A>(), type_name::<B>())) } pub fn try_type_coerce<A, B>(a: A) -> Option<B> { trait Eq<B> { fn eq(self) -> Option<B>; } struct Foo<A, B>(A, PhantomData<fn(B)>); impl<A, B> Eq<B> for Foo<A, B> { default fn eq(self) -> Option<B> { None } } impl<A> Eq<A> for Foo<A, A> { fn eq(self) -> Option<A> { Some(self.0) } } Foo::<A, B>(a, PhantomData).eq() }