//! Parallel iterator types for [results][std::result]
//!
//! You will rarely need to interact with this module directly unless you need
//! to name one of the iterator types.
//!
//! [std::result]: https://doc.rust-lang.org/stable/std/result/

use crate::iter::plumbing::*;
use crate::iter::*;
use std::sync::Mutex;

use crate::option;

/// Parallel iterator over a result
#[derive(Debug, Clone)]
pub struct IntoIter<T: Send> {
    inner: option::IntoIter<T>,
}

impl<T: Send, E> IntoParallelIterator for Result<T, E> {
    type Item = T;
    type Iter = IntoIter<T>;

    fn into_par_iter(self) -> Self::Iter {
        IntoIter {
            inner: self.ok().into_par_iter(),
        }
    }
}

delegate_indexed_iterator! {
    IntoIter<T> => T,
    impl<T: Send>
}

/// Parallel iterator over an immutable reference to a result
#[derive(Debug)]
pub struct Iter<'a, T: Sync> {
    inner: option::IntoIter<&'a T>,
}

impl<'a, T: Sync> Clone for Iter<'a, T> {
    fn clone(&self) -> Self {
        Iter {
            inner: self.inner.clone(),
        }
    }
}

impl<'a, T: Sync, E> IntoParallelIterator for &'a Result<T, E> {
    type Item = &'a T;
    type Iter = Iter<'a, T>;

    fn into_par_iter(self) -> Self::Iter {
        Iter {
            inner: self.as_ref().ok().into_par_iter(),
        }
    }
}

delegate_indexed_iterator! {
    Iter<'a, T> => &'a T,
    impl<'a, T: Sync + 'a>
}

/// Parallel iterator over a mutable reference to a result
#[derive(Debug)]
pub struct IterMut<'a, T: Send> {
    inner: option::IntoIter<&'a mut T>,
}

impl<'a, T: Send, E> IntoParallelIterator for &'a mut Result<T, E> {
    type Item = &'a mut T;
    type Iter = IterMut<'a, T>;

    fn into_par_iter(self) -> Self::Iter {
        IterMut {
            inner: self.as_mut().ok().into_par_iter(),
        }
    }
}

delegate_indexed_iterator! {
    IterMut<'a, T> => &'a mut T,
    impl<'a, T: Send + 'a>
}

/// Collect an arbitrary `Result`-wrapped collection.
///
/// If any item is `Err`, then all previous `Ok` items collected are
/// discarded, and it returns that error.  If there are multiple errors, the
/// one returned is not deterministic.
impl<C, T, E> FromParallelIterator<Result<T, E>> for Result<C, E>
where
    C: FromParallelIterator<T>,
    T: Send,
    E: Send,
{
    fn from_par_iter<I>(par_iter: I) -> Self
    where
        I: IntoParallelIterator<Item = Result<T, E>>,
    {
        fn ok<T, E>(saved: &Mutex<Option<E>>) -> impl Fn(Result<T, E>) -> Option<T> + '_ {
            move |item| match item {
                Ok(item) => Some(item),
                Err(error) => {
                    // We don't need a blocking `lock()`, as anybody
                    // else holding the lock will also be writing
                    // `Some(error)`, and then ours is irrelevant.
                    if let Ok(mut guard) = saved.try_lock() {
                        if guard.is_none() {
                            *guard = Some(error);
                        }
                    }
                    None
                }
            }
        }

        let saved_error = Mutex::new(None);
        let collection = par_iter
            .into_par_iter()
            .map(ok(&saved_error))
            .while_some()
            .collect();

        match saved_error.into_inner().unwrap() {
            Some(error) => Err(error),
            None => Ok(collection),
        }
    }
}
