use super::super::{annotations::*, r#struct::*, traits::*};
use kutil::std::error::*;
pub struct ErrorReceiverWithFallbackAnnotations<'own, InnerT> {
pub inner: &'own mut InnerT,
pub fallback_annotations: Option<&'own Annotations>,
}
impl<'own, InnerT> ErrorReceiverWithFallbackAnnotations<'own, InnerT> {
pub fn new(inner: &'own mut InnerT, fallback_annotations: Option<&'own Annotations>) -> Self {
Self { inner, fallback_annotations }
}
}
impl<'own, ErrorT, InnerT> ErrorReceiver<ErrorT> for ErrorReceiverWithFallbackAnnotations<'own, InnerT>
where
ErrorT: Annotated,
InnerT: ErrorReceiver<ErrorT>,
{
fn give_error(&mut self, error: ErrorT) -> Result<(), ErrorT> {
if !error.has_annotations()
&& let Some(annotations) = self.fallback_annotations
{
self.inner.give_error(error.with_annotations(annotations.clone()))
} else {
self.inner.give_error(error)
}
}
}
pub trait WithFallbackAnnotations<'own, ErrorT, InnerT> {
fn with_fallback_annotations(
&'own mut self,
annotations: Option<&'own Annotations>,
) -> ErrorReceiverWithFallbackAnnotations<'own, InnerT>;
fn with_fallback_annotations_from_field<StructT>(
&'own mut self,
r#struct: &'own StructT,
name: &str,
) -> ErrorReceiverWithFallbackAnnotations<'own, InnerT>
where
StructT: AnnotatedStruct,
{
self.with_fallback_annotations(r#struct.field_or_struct_annotations(name))
}
fn with_fallback_annotations_from_struct<StructT>(
&'own mut self,
r#struct: &'own StructT,
) -> ErrorReceiverWithFallbackAnnotations<'own, InnerT>
where
StructT: AnnotatedStruct,
{
self.with_fallback_annotations(r#struct.struct_annotations())
}
}
impl<'own, ErrorT, ErrorReceiverT> WithFallbackAnnotations<'own, ErrorT, ErrorReceiverT> for ErrorReceiverT
where
ErrorT: Annotated,
ErrorReceiverT: ErrorReceiver<ErrorT>,
{
fn with_fallback_annotations(
&'own mut self,
annotations: Option<&'own Annotations>,
) -> ErrorReceiverWithFallbackAnnotations<'own, ErrorReceiverT> {
ErrorReceiverWithFallbackAnnotations::new(self, annotations)
}
}
#[macro_export]
macro_rules! errors_with_fallback_annotations_from_field {
( $new_errors:ident, $errors:expr, $self:expr, $field:expr, $( $code:tt )* ) => {
{
let annotations = $self.field_or_struct_annotations($field).cloned();
let $new_errors = &mut $errors.with_fallback_annotations(annotations.as_ref());
$( $code )*
}
};
}
#[allow(unused_imports)]
pub use errors_with_fallback_annotations_from_field;