use super::{
super::{attachment::*, error::*, implementation::*, problem::*},
comparison::*,
equality::*,
r#ref::*,
};
use std::{cmp::*, error::*};
#[derive(Debug)]
pub struct Cause {
pub error: CapturedError,
pub attachments: Vector<CapturedAttachment>,
}
impl Cause {
pub fn new(error: CapturedError) -> Self {
Self {
error,
attachments: Default::default(),
}
}
pub fn to_ref<'problem>(
&'problem self,
problem: &'problem Problem,
depth: usize,
) -> CauseRef<'problem, CapturedError> {
CauseRef::new(problem, depth, &self.error, &self.attachments)
}
}
impl Errors for Cause {
fn iter_errors_of_type<'this, ErrorT>(&'this self) -> impl Iterator<Item = &'this ErrorT>
where
ErrorT: 'static + Error,
{
self.iter_sources()
.filter_map(|error| error.downcast_ref::<ErrorT>())
}
}
impl IterateErrorSources for Cause {
fn iter_sources<'this>(&'this self) -> ErrorSourceIterator<'this> {
ErrorSourceIterator::new(self.error.as_ref())
}
}
impl Attachments for Cause {
fn attachments(&self) -> impl Iterator<Item = &CapturedAttachment> {
self.attachments.iter()
}
}
impl AttachmentsMut for Cause {
fn attachments_mut(&mut self) -> impl Iterator<Item = &mut CapturedAttachment> {
self.attachments.iter_mut()
}
fn attach<AttachmentT>(&mut self, attachment: AttachmentT)
where
AttachmentT: 'static + Send + Sync,
{
self.attachments.push(Box::new(attachment));
}
}
impl PartialEq for Cause {
fn eq(&self, other: &Self) -> bool {
if let Some(equality) = self.attachment_of_type::<CauseEquality>() {
equality.eq(self, other)
} else {
self.partial_cmp(other) == Some(Ordering::Equal)
}
}
}
impl Eq for Cause {}
impl PartialOrd for Cause {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.attachment_of_type::<CauseComparison>()
.and_then(|comparison| comparison.compare(self, other))
}
}
impl<'this> IntoIterator for &'this Cause {
type Item = &'this (dyn 'static + Error);
type IntoIter = ErrorSourceIterator<'this>;
fn into_iter(self) -> Self::IntoIter {
self.iter_sources()
}
}
impl<ErrorT> From<ErrorT> for Cause
where
ErrorT: 'static + Error + Send + Sync,
{
fn from(error: ErrorT) -> Self {
Self::new(error.into())
}
}