use crate::infallible::{Xap, XapOne};
use crate::infallible_use::{XapUse, XapUseOne};
use crate::sizes::{Many, One, size_pair::SizePair};
use core::iter::FusedIterator;
#[derive(Clone, Copy, Default)]
pub struct OneMany;
impl SizePair for OneMany {
type S1 = One;
type S2 = Many;
type ThenBin = OneMany;
type ThenMany = OneMany;
fn transformed_size_hint(_: (usize, Option<usize>)) -> (usize, Option<usize>) {
(0, None)
}
type XapOptResult<M, X1, X2>
= IterOptOneMany<<X2::Values as IntoIterator>::IntoIter>
where
X1: Xap<O = Option<M>, Size = Self::S1>,
X2: Xap<I = M, Size = Self::S2>;
fn xap_opt<M, X1, X2>(x1: X1, x2: X2, i: X1::I) -> Self::XapOptResult<M, X1, X2>
where
X1: Xap<O = Option<M>, Size = Self::S1>,
X2: Xap<I = M, Size = Self::S2>,
{
match x1.one_value(i) {
Some(a) => IterOptOneMany::ok(x2.xap(a).into_iter()),
None => IterOptOneMany::err(),
}
}
type XapResResult<M, E, X1, X2>
= IterResOneMany<<X2::Values as IntoIterator>::IntoIter, E>
where
X1: Xap<O = Result<M, E>, Size = Self::S1>,
X2: Xap<I = M, Size = Self::S2>;
#[inline(always)]
fn xap_res<M, E, X1, X2>(x1: X1, x2: X2, i: X1::I) -> Self::XapResResult<M, E, X1, X2>
where
X1: Xap<O = Result<M, E>, Size = Self::S1>,
X2: Xap<I = M, Size = Self::S2>,
{
match x1.one_value(i) {
Ok(a) => IterResOneMany::ok(x2.xap(a).into_iter()),
Err(e) => IterResOneMany::err(e),
}
}
type XapUseOptResult<M, X1, X2>
= IterUseOptOneMany<<X2::Values as IntoIterator>::IntoIter>
where
X1: XapUse<O = Option<M>, Size = Self::S1>,
X2: XapUse<U = X1::U, I = M, Size = Self::S2>;
#[inline]
fn xap_use_opt<M, X1, X2>(
u: *mut X1::U,
x1: X1,
x2: X2,
i: X1::I,
) -> Self::XapUseOptResult<M, X1, X2>
where
X1: XapUse<O = Option<M>, Size = Self::S1>,
X2: XapUse<U = X1::U, I = M, Size = Self::S2>,
{
match x1.one_value(u, i) {
Some(a) => IterUseOptOneMany::ok(x2.xap_use(u, a).into_iter()),
None => IterUseOptOneMany::err(),
}
}
type XapUseResResult<M, E, X1, X2>
= IterUseResOneMany<<X2::Values as IntoIterator>::IntoIter, E>
where
X1: XapUse<O = Result<M, E>, Size = Self::S1>,
X2: XapUse<U = X1::U, I = M, Size = Self::S2>;
#[inline]
fn xap_use_res<M, E, X1, X2>(
u: *mut X1::U,
x1: X1,
x2: X2,
i: X1::I,
) -> Self::XapUseResResult<M, E, X1, X2>
where
X1: XapUse<O = Result<M, E>, Size = Self::S1>,
X2: XapUse<U = X1::U, I = M, Size = Self::S2>,
{
match x1.one_value(u, i) {
Ok(a) => IterUseResOneMany::ok(x2.xap_use(u, a).into_iter()),
Err(e) => IterUseResOneMany::err(e),
}
}
}
pub enum IterOptOneMany<I: Iterator> {
Success(I),
Fail(bool),
}
impl<I: Iterator> IterOptOneMany<I> {
pub fn ok(i: I) -> Self {
Self::Success(i)
}
pub fn err() -> Self {
Self::Fail(false)
}
}
impl<I: Iterator> Iterator for IterOptOneMany<I> {
type Item = Option<I::Item>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self {
Self::Success(iter) => iter.next().map(Some),
Self::Fail(taken) => {
match taken {
false => {
*taken = true;
Some(None)
}
true => None, }
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
Self::Success(iter) => iter.size_hint(),
Self::Fail(false) => (1, Some(1)),
Self::Fail(true) => (0, Some(0)),
}
}
#[inline]
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
match self {
Self::Success(iter) => iter.map(Some).fold(init, f),
Self::Fail(false) => f(init, None),
Self::Fail(true) => init,
}
}
#[inline]
fn count(self) -> usize
where
Self: Sized,
{
match self {
Self::Success(iter) => iter.count(),
Self::Fail(false) => 1,
Self::Fail(true) => 0,
}
}
}
impl<I: FusedIterator> FusedIterator for IterOptOneMany<I> {}
impl<I: ExactSizeIterator> ExactSizeIterator for IterOptOneMany<I> {
fn len(&self) -> usize {
match self {
Self::Success(iter) => iter.len(),
Self::Fail(false) => 1,
Self::Fail(true) => 0,
}
}
}
pub enum IterResOneMany<I: Iterator, E> {
Success(I),
Fail(Option<E>),
}
impl<I: Iterator, E> IterResOneMany<I, E> {
pub fn ok(i: I) -> Self {
Self::Success(i)
}
pub fn err(e: E) -> Self {
Self::Fail(Some(e))
}
}
impl<I: Iterator, E> Iterator for IterResOneMany<I, E> {
type Item = Result<I::Item, E>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self {
Self::Success(iter) => iter.next().map(Ok),
Self::Fail(e) => match e.is_some() {
true => {
Some(Err(unsafe { e.take().unwrap_unchecked() }))
}
false => None, },
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
Self::Success(iter) => iter.size_hint(),
Self::Fail(Some(_)) => (1, Some(1)),
Self::Fail(None) => (0, Some(0)),
}
}
#[inline]
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
match self {
Self::Success(iter) => iter.map(Ok).fold(init, f),
Self::Fail(Some(e)) => f(init, Err(e)),
Self::Fail(None) => init,
}
}
#[inline]
fn count(self) -> usize
where
Self: Sized,
{
match self {
Self::Success(iter) => iter.count(),
Self::Fail(Some(_)) => 1,
Self::Fail(None) => 0,
}
}
}
impl<I: FusedIterator, E> FusedIterator for IterResOneMany<I, E> {}
impl<I: ExactSizeIterator, E> ExactSizeIterator for IterResOneMany<I, E> {
fn len(&self) -> usize {
match self {
Self::Success(iter) => iter.len(),
Self::Fail(Some(_)) => 1,
Self::Fail(None) => 0,
}
}
}
pub enum IterUseOptOneMany<I: Iterator> {
Success(I),
Fail(bool),
}
impl<I: Iterator> IterUseOptOneMany<I> {
pub fn ok(i: I) -> Self {
Self::Success(i)
}
pub fn err() -> Self {
Self::Fail(false)
}
}
impl<I: Iterator> Iterator for IterUseOptOneMany<I> {
type Item = Option<I::Item>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self {
Self::Success(iter) => iter.next().map(Some),
Self::Fail(taken) => match taken {
false => {
*taken = true;
Some(None)
}
true => None, },
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
Self::Success(iter) => iter.size_hint(),
Self::Fail(false) => (1, Some(1)),
Self::Fail(true) => (0, Some(0)),
}
}
#[inline]
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
match self {
Self::Success(iter) => iter.map(Some).fold(init, f),
Self::Fail(false) => f(init, None),
Self::Fail(true) => init,
}
}
#[inline]
fn count(self) -> usize
where
Self: Sized,
{
match self {
Self::Success(iter) => iter.count(),
Self::Fail(false) => 1,
Self::Fail(true) => 0,
}
}
}
impl<I: FusedIterator> FusedIterator for IterUseOptOneMany<I> {}
impl<I: ExactSizeIterator> ExactSizeIterator for IterUseOptOneMany<I> {
fn len(&self) -> usize {
match self {
Self::Success(iter) => iter.len(),
Self::Fail(false) => 1,
Self::Fail(true) => 0,
}
}
}
pub enum IterUseResOneMany<I: Iterator, E> {
Success(I),
Fail(Option<E>),
}
impl<I: Iterator, E> IterUseResOneMany<I, E> {
pub fn ok(i: I) -> Self {
Self::Success(i)
}
pub fn err(e: E) -> Self {
Self::Fail(Some(e))
}
}
impl<I: Iterator, E> Iterator for IterUseResOneMany<I, E> {
type Item = Result<I::Item, E>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self {
Self::Success(iter) => iter.next().map(Ok),
Self::Fail(e) => match e.is_some() {
true => {
Some(Err(unsafe { e.take().unwrap_unchecked() }))
}
false => None, },
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
Self::Success(iter) => iter.size_hint(),
Self::Fail(Some(_)) => (1, Some(1)),
Self::Fail(None) => (0, Some(0)),
}
}
#[inline]
fn fold<B, F>(self, init: B, mut f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
match self {
Self::Success(iter) => iter.map(Ok).fold(init, f),
Self::Fail(Some(e)) => f(init, Err(e)),
Self::Fail(None) => init,
}
}
#[inline]
fn count(self) -> usize
where
Self: Sized,
{
match self {
Self::Success(iter) => iter.count(),
Self::Fail(Some(_)) => 1,
Self::Fail(None) => 0,
}
}
}
impl<I: FusedIterator, E> FusedIterator for IterUseResOneMany<I, E> {}
impl<I: ExactSizeIterator, E> ExactSizeIterator for IterUseResOneMany<I, E> {
fn len(&self) -> usize {
match self {
Self::Success(iter) => iter.len(),
Self::Fail(Some(_)) => 1,
Self::Fail(None) => 0,
}
}
}