<commit_before>//! This crate exposes a `Single` trait for extracting the element from a
//! single-element iterator (or `panic!`ing if that precondition is false).

/// Trait to extract the element from a single-element iterator.
pub trait Single {
    /// The item type of the wrapped iterator.
    type Item;

    /// Get the single element from a single-element iterator.
    ///
    /// Note that many iterators return references to the elements,
    /// so this method will as well if the backing iterator does.
    ///
    /// # Panics
    ///
    /// Panics if the iterator is empty or has more than one element.
    ///
    /// # Examples
    ///
    /// An empty iterator panics:
    ///
    /// ```should_panic(expected = "Asked empty iterator for single element")
    /// # use single::Single;
    /// # use std::iter;
    /// # let _: i32 =
    /// iter::empty().single();
    /// ```
    ///
    /// An iterator with multiple elements panics:
    ///
    /// ```should_panic(expected = "Asked iterator with multiple elements for single element")
    /// # use single::Single;
    /// # use std::iter;
    /// iter::repeat(0).single();
    /// ```
    ///
    /// An iterator with a single element returns that element:
    ///
    /// ```
    /// # use single::Single;
    /// # use std::iter;
    /// assert_eq!(iter::once(0).single(), 0);
    /// ```
    fn single(self) -> Self::Item;

    /// Get the single element from an iterator or a default fallback value.
    ///
    /// Note that many iterators return references to the elements,
    /// so this method will as well if the backing iterator does.
    ///
    /// # Examples
    ///
    /// An empty iterator will return the fallback:
    ///
    /// ```
    /// # use single::Single;
    /// # use std::iter;
    /// assert_eq!(iter::empty().single_or(5), 5)
    /// ```
    ///
    /// An iterator with multiple elements will return the fallback:
    ///
    /// ```
    /// # use single::Single;
    /// # use std::iter;
    /// assert_eq!(iter::repeat(0).single_or(5), 5)
    /// ```
    ///
    /// An iterator with a single element returns that element:
    ///
    /// ```
    /// # use single::Single;
    /// # use std::iter;
    /// assert_eq!(iter::once(0).single_or(5), 0)
    /// ```
    fn single_or(self, default: Self::Item) -> Self::Item;

    /// Get the single element from an iterator or from a default provider.
    ///
    /// Note that many iterators return references to the elements,
    /// so this method will as well if the backing iterator does.
    ///
    /// # Examples
    ///
    /// An empty iterator will return the fallback:
    ///
    /// ```
    /// # use single::Single;
    /// # use std::iter;
    /// assert_eq!(iter::empty().single_or_else(|| 5), 5)
    /// ```
    ///
    /// An iterator with multiple elements will return the fallback:
    ///
    /// ```
    /// # use single::Single;
    /// # use std::iter;
    /// assert_eq!(iter::repeat(0).single_or_else(|| 5), 5)
    /// ```
    ///
    /// An iterator with a single element returns that element:
    ///
    /// ```
    /// # use single::Single;
    /// # use std::iter;
    /// assert_eq!(iter::once(0).single_or_else(|| 5), 0)
    /// ```
    fn single_or_else<F>(self, default_fn: F) -> Self::Item
        where F: FnOnce() -> Self::Item;
}

impl<I> Single for I where I: Iterator {
    type Item = <Self as Iterator>::Item;

    fn single(mut self) -> Self::Item {
        match self.next() {
            None => panic!("Asked empty iterator for single element"),
            Some(element) => if let Some(_) = self.next() {
                panic!("Asked iterator with multiple elements for single element")
            } else { element }
        }
    }

    fn single_or(self, default: Self::Item) -> Self::Item {
        self.single_or_else(|| default)
    }

    fn single_or_else<F>(mut self, default_fn: F) -> Self::Item
        where F: FnOnce() -> Self::Item
    {
        match self.next() {
            None => default_fn(),
            Some(element) => if let Some(_) = self.next() {
                default_fn()
            } else { element }
        }
    }
}

<commit_msg>Make single::Single::single return a result::Result<commit_after>//! This crate exposes a `Single` trait for extracting the element from a
//! single-element iterator (or `panic!`ing if that precondition is false).

use std::{fmt, error, result};

type Result<T> = result::Result<T, self::Error>;

/// Trait to extract the element from a single-element iterator.
pub trait Single {
    /// The item type of the wrapped iterator.
    type Item;

    /// Get the single element from a single-element iterator.
    ///
    /// Note that many iterators return references to the elements,
    /// so this method will as well if the backing iterator does.
    ///
    /// # Examples
    ///
    /// ```
    /// # use single::{ self, Single };
    /// # use std::iter;
    /// assert_eq!(iter::empty::<i32>().single(), Err(single::Error::NoElements));
    /// assert_eq!(iter::once(0).single(), Ok(0));
    /// assert_eq!(iter::repeat(0).single(), Err(single::Error::MultipleElements));
    /// ```
    fn single(self) -> Result<Self::Item>;
}

/// An error in the execution of [`single::Single::single`](trait.Single.html#tymethod.single).
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Error {
    /// Asked empty iterator for single element.
    NoElements,
    /// Asked iterator with multiple elements for single element.
    MultipleElements,
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(self, f)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::NoElements => write!(
                f,
                "SingleError::NoElements: {}",
                error::Error::description(self),
            ),
            Error::MultipleElements => write!(
                f,
                "SingleError::MultipleElements: {}",
                error::Error::description(self),
            ),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::NoElements => "Asked empty iterator for single element",
            Error::MultipleElements => "Asked iterator with multiple elements for single element",
        }
    }
    fn cause(&self) -> Option<&error::Error> { None }
}

impl<I> Single for I where I: Iterator {
    type Item = <Self as Iterator>::Item;

    fn single(mut self) -> Result<Self::Item> {
        match self.next() {
            None => Err(Error::NoElements),
            Some(element) => if self.next().is_none() {
                Ok(element)
            } else {
                Err(Error::MultipleElements)
            }
        }
    }
}

#[cfg(test)]
mod test {
    use std::iter;
    use super::Single;

    #[test]
    #[should_panic(expected = "Asked empty iterator for single element")]
    fn panic_empty() { let _: i32 = iter::empty().single().unwrap(); }

    #[test]
    #[should_panic(expected = "Asked iterator with multiple elements for single element")]
    fn panic_multiple() { let _ = iter::repeat(0).single().unwrap(); }
}
{'fraction_non_alphanumeric': 0.16572452778160762, 'fraction_numerical': 0.003998345512201847, 'mean_word_length': 2.032608695652174, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5160566', 'n_tokens_mistral': 2097, 'n_tokens_neox': 2076, 'n_words': 631}