#![cfg_attr(not(feature = "std"), no_std)]
#![forbid(
missing_debug_implementations,
unconditional_recursion,
future_incompatible
)]
#![deny(bad_style, missing_docs, unsafe_code, unused)]
#![allow(deprecated)]
# instead"
)]
#[macro_use]
extern crate failure;
#[cfg(not(feature = "std"))]
use core as std;
#[allow(missing_docs)]
#[deprecated(
since = "1.0.1",
note = "use [`Itertools::at_most_one`](https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.at_most_one) instead"
)]
pub trait Single: Iterator {
#[deprecated(
since = "1.0.1",
note = "use [`Itertools::at_most_one`](https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.at_most_one) instead"
)]
fn single(self) -> Result<Self::Item, Error>;
}
#[derive(Copy, Clone, Eq, PartialEq, Fail)]
pub enum Error {
#[fail(display = "Called single() on empty iterator")]
NoElements,
#[fail(display = "Called single() on multiple-element iterator")]
MultipleElements,
}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self)
}
}
impl<I: Iterator> Single for I {
fn single(mut self) -> Result<Self::Item, Error> {
match self.next() {
None => Err(Error::NoElements),
Some(element) => match self.next() {
None => Ok(element),
Some(_) => Err(Error::MultipleElements),
},
}
}
}
#[cfg(test)]
mod test {
use super::Single;
use std::iter;
#[test]
#[should_panic(expected = "Called single() on empty iterator")]
fn panic_empty() {
let _: i32 = iter::empty().single().unwrap();
}
#[test]
#[should_panic(expected = "Called single() on multiple-element iterator")]
fn panic_multiple() {
let _ = iter::repeat(0).single().unwrap();
}
}