1#![cfg_attr(not(feature = "std"), no_std)]
18#![forbid(
19    missing_debug_implementations,
20    unconditional_recursion,
21    future_incompatible
22)]
23#![deny(bad_style, missing_docs, unsafe_code, unused)]
24#![allow(deprecated)]
25# instead"
28)]
29
30#[macro_use]
31extern crate failure;
32#[cfg(not(feature = "std"))]
33use core as std;
34
35#[allow(missing_docs)]
36#[deprecated(
37    since = "1.0.1",
38    note = "use [`Itertools::at_most_one`](https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.at_most_one) instead"
39)]
40pub trait Single: Iterator {
41    #[deprecated(
53        since = "1.0.1",
54        note = "use [`Itertools::at_most_one`](https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.at_most_one) instead"
55    )]
56    fn single(self) -> Result<Self::Item, Error>;
57}
58
59#[derive(Copy, Clone, Eq, PartialEq, Fail)]
61pub enum Error {
62    #[fail(display = "Called single() on empty iterator")]
64    NoElements,
65
66    #[fail(display = "Called single() on multiple-element iterator")]
68    MultipleElements,
69}
70
71impl std::fmt::Debug for Error {
72    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
73        write!(f, "{}", self)
74    }
75}
76
77impl<I: Iterator> Single for I {
78    fn single(mut self) -> Result<Self::Item, Error> {
79        match self.next() {
80            None => Err(Error::NoElements),
81            Some(element) => match self.next() {
82                None => Ok(element),
83                Some(_) => Err(Error::MultipleElements),
84            },
85        }
86    }
87}
88
89#[cfg(test)]
90mod test {
91    use super::Single;
92    use std::iter;
93
94    #[test]
95    #[should_panic(expected = "Called single() on empty iterator")]
96    fn panic_empty() {
97        let _: i32 = iter::empty().single().unwrap();
98    }
99
100    #[test]
101    #[should_panic(expected = "Called single() on multiple-element iterator")]
102    fn panic_multiple() {
103        let _ = iter::repeat(0).single().unwrap();
104    }
105}