single/
lib.rs

1//! THIS CRATE IS DEPRECATED. Use [`Itertools::at_most_one`](https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.at_most_one) instead.
2//!
3//! Provides the `Single` trait for extracting the element from a
4//! single-element iterator.
5//!
6//! # Examples
7//!
8//! ```
9//! use single::{ Single, Error };
10//! use std::iter;
11//!
12//! assert_eq!(iter::empty::<i32>().single(), Err(Error::NoElements));
13//! assert_eq!(iter::once(0).single(), Ok(0));
14//! assert_eq!(iter::repeat(0).single(), Err(Error::MultipleElements));
15//! ```
16
17#![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#![deprecated(
26    since = "1.0.1",
27    note = "use [`Itertools::at_most_one`](https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.at_most_one) 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    /// Get the single element from a single-element iterator.
42    ///
43    /// # Examples
44    ///
45    /// ```
46    /// # use single::{ Single, Error };
47    /// # use std::iter;
48    /// assert_eq!(iter::empty::<i32>().single(), Err(Error::NoElements));
49    /// assert_eq!(iter::once(0).single(), Ok(0));
50    /// assert_eq!(iter::repeat(0).single(), Err(Error::MultipleElements));
51    /// ```
52    #[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/// An error in the execution of [`Single::single`](trait.Single.html#tymethod.single).
60#[derive(Copy, Clone, Eq, PartialEq, Fail)]
61pub enum Error {
62    /// Asked an empty iterator for the single element.
63    #[fail(display = "Called single() on empty iterator")]
64    NoElements,
65
66    /// Asked an iterator with multiple elements for the single element.
67    #[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}