use super::super::{
super::{annotate::*, normal::*},
errors::*,
resolve::*,
};
use {
kutil::std::error::*,
std::{fmt, marker::*},
};
pub fn resolve_try_from<TryFromT, IntermediateT, AnnotatedT, ErrorReceiverT>(
variant: Variant<AnnotatedT>,
errors: &mut ErrorReceiverT,
) -> ResolveResult<TryFromT, AnnotatedT>
where
Variant<AnnotatedT>: TryInto<IntermediateT>,
<Variant<AnnotatedT> as TryInto<IntermediateT>>::Error: fmt::Display,
TryFromT: TryFrom<IntermediateT>,
TryFromT::Error: fmt::Display,
AnnotatedT: Annotated + Clone + Default,
ErrorReceiverT: ErrorReceiver<ResolveError<AnnotatedT>>,
{
let maybe_annotations = variant.maybe_annotations();
let intermediate: IntermediateT = match variant.try_into() {
Ok(intermediate) => intermediate,
Err(error) => {
errors.give(
MalformedError::new(tynm::type_name::<IntermediateT>(), error.to_string())
.with_annotations_from(&maybe_annotations),
)?;
return Ok(None);
}
};
Ok(match intermediate.try_into() {
Ok(resolved) => Some(resolved),
Err(error) => {
errors.give(
MalformedError::new(tynm::type_name::<TryFromT>(), error.to_string())
.with_annotations_from(&maybe_annotations),
)?;
None
}
})
}
#[derive(Clone, Default, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ResolveTryFrom<InnerT, IntermediateT> {
pub inner: InnerT,
intermediate: PhantomData<IntermediateT>,
}
impl<InnerT, IntermediateT> ResolveTryFrom<InnerT, IntermediateT> {
pub fn new(inner: InnerT) -> Self {
Self { inner, intermediate: PhantomData }
}
}
impl<InnerT, IntermediateT, AnnotatedT> Resolve<ResolveTryFrom<InnerT, IntermediateT>, AnnotatedT>
for Variant<AnnotatedT>
where
Variant<AnnotatedT>: TryInto<IntermediateT>,
<Variant<AnnotatedT> as TryInto<IntermediateT>>::Error: fmt::Display,
InnerT: TryFrom<IntermediateT>,
InnerT::Error: fmt::Display,
AnnotatedT: Annotated + Clone + Default,
{
fn resolve_with_errors<ErrorReceiverT>(
self,
errors: &mut ErrorReceiverT,
) -> ResolveResult<ResolveTryFrom<InnerT, IntermediateT>, AnnotatedT>
where
ErrorReceiverT: ErrorReceiver<ResolveError<AnnotatedT>>,
{
resolve_try_from(self, errors).map(|resolved| resolved.map(ResolveTryFrom::new))
}
}
impl<InnerT, IntermediateT> AsRef<InnerT> for ResolveTryFrom<InnerT, IntermediateT> {
fn as_ref(&self) -> &InnerT {
&self.inner
}
}
impl<InnerT, IntermediateT> From<InnerT> for ResolveTryFrom<InnerT, IntermediateT> {
fn from(inner: InnerT) -> Self {
Self::new(inner)
}
}
impl<InnerT, IntermediateT> fmt::Display for ResolveTryFrom<InnerT, IntermediateT>
where
InnerT: fmt::Display,
{
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.inner, formatter)
}
}