#[cfg(feature = "alloc")]
use alloc::boxed::Box;
use core::error::Error;
use core::fmt::{Debug, Display, Formatter};
use display_as_debug::fmt::DebugStructExt;
use display_as_debug::types::{Full, Short};
use display_as_debug::wrap::TypeNameResult;
use tap::Pipe;
#[subdef::subdef]
pub struct ResultCollectError<E, C, CErr, I> {
#[cfg(doc)]
pub error: E,
#[cfg(doc)]
pub result: Result<C, CErr>,
#[cfg(doc)]
pub iter: I,
#[cfg(all(not(doc), feature = "alloc"))]
data: Box<ResultCollectErrorData<E, C, CErr, I>>,
#[cfg(all(not(doc), not(feature = "alloc")))]
data: ResultCollectErrorData<E, C, CErr, I>,
}
#[doc(hidden)]
pub struct ResultCollectErrorData<E, C, CErr, I> {
pub error: E,
pub result: Result<C, CErr>,
pub iter: I,
}
#[doc(hidden)]
impl<E, C, CErr, I> ResultCollectError<E, C, CErr, I> {
#[must_use]
#[cfg(feature = "alloc")]
pub fn new(error: E, result: Result<C, CErr>, iter: I) -> Self {
ResultCollectErrorData { error, result, iter }.pipe(Box::new).pipe(|data| Self { data })
}
#[must_use]
#[cfg(not(feature = "alloc"))]
pub fn new(error: E, result: Result<C, CErr>, iter: I) -> Self {
ResultCollectErrorData { error, result, iter }.pipe(|data| Self { data })
}
}
impl<E, C, CErr, I> ResultCollectError<E, C, CErr, I> {
#[must_use]
#[cfg(feature = "alloc")]
pub fn into_data(self) -> ResultCollectErrorData<E, C, CErr, I> {
*self.data
}
#[must_use]
#[cfg(not(feature = "alloc"))]
pub fn into_data(self) -> ResultCollectErrorData<E, C, CErr, I> {
self.data
}
}
#[doc(hidden)]
impl<E, C, CErr, I> core::ops::Deref for ResultCollectError<E, C, CErr, I> {
type Target = ResultCollectErrorData<E, C, CErr, I>;
fn deref(&self) -> &Self::Target {
&self.data
}
}
#[doc(hidden)]
#[allow(clippy::missing_fields_in_debug, reason = "All data is covered")]
impl<E: Debug, C, CErr: Debug, I> Debug for ResultCollectErrorData<E, C, CErr, I> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("ResultCollectErrorData")
.field("error", &self.error)
.field("result", &TypeNameResult::borrow::<Short>(&self.result))
.field_type::<I, Full>("iter")
.finish()
}
}
impl<E: Debug, C, CErr: Debug, I> Debug for ResultCollectError<E, C, CErr, I> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("ResultCollectError")
.field("error", &self.data.error)
.field("result", &TypeNameResult::borrow::<Short>(&self.data.result))
.field_type::<I, Full>("iter")
.finish()
}
}
impl<E: Display, C, CErr: Display, I> Display for ResultCollectError<E, C, CErr, I> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "Iterator error: {}", self.data.error).and_then(|()| match &self.data.result {
Err(e) => write!(f, "; Collection error: {e}"),
_ => Ok(()),
})
}
}
impl<E: Error + 'static, C, CErr: Error, I> Error for ResultCollectError<E, C, CErr, I> {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(&self.data.error)
}
}