use const_panic::PanicVal;
use crate::internal::*;
pub const fn generate_msg_for_match_err<A : GetErrorSet,B : GetErrorSet>(ignore_unthrown : bool) -> Option<Message>
{
let uncaught = ErrorSet::subtract(A::COLLECTION, B::COLLECTION);
let unnecessary = ErrorSet::subtract(B::COLLECTION, A::COLLECTION);
let mut message = Message::new();
let mut error : bool = false;
if uncaught.length != 0 && (!ignore_unthrown)
{
message = message.append_str("Uncaught errors: ");
message = message.append_error_set(uncaught);
error = true;
}
if uncaught.length != 0 && unnecessary.length != 0 && (!ignore_unthrown)
{
message = message.append_str(". ");
}
if unnecessary.length != 0
{
message = message.append_str("Unnecessary caught errors: ");
message = message.append_error_set(unnecessary);
error = true;
}
if error {
Some(message)
} else {
None
}
}
#[macro_export]
macro_rules! into_err {
($e : expr) => {$e.map_err(|u|{
use ::error_union::internal::WrapError;
u.wrap_error().map(|u|{
fn internal<Input : ::error_union::internal::GetErrorSet,Output : ::error_union::internal::GetErrorSet>(input : ::error_union::internal::Error<Input>) -> ::error_union::internal::Error<Output>
{
struct Holder<A : ::error_union::internal::GetErrorSet,B : ::error_union::internal::GetErrorSet>(::std::marker::PhantomData<A>, ::std::marker::PhantomData<B>);
impl<A : ::error_union::internal::GetErrorSet,B : ::error_union::internal::GetErrorSet> Holder<A,B>
{
const ASSERT: bool = {
let missing = ::error_union::internal::ErrorSet::subtract(A::COLLECTION, B::COLLECTION);
if missing.length != 0
{
let mut msg = ::error_union::internal::Message::new();
msg = msg.append_str("Tried to propagate errors not in function return: ");
msg = msg.append_error_set(missing);
::error_union::internal::concat_panic(&[&msg.message]);
} else {
false
}
};
}
if Holder::<Input, Output>::ASSERT
{
unreachable!()
}
input.into_err_unchecked()
}
internal(u)
})})};
}
#[macro_export]
macro_rules! as_true {
($($t : tt)*) => {true}
}
#[macro_export]
macro_rules! match_err {
($e:expr, Ok($ok_ident : ident) => $ok_arm : expr, $($err_i : ident $(: $err_type : ty => $err_arm : expr)? $(=> $err_guard: expr)? ,)*) =>
{
const HAS_UNDERSCORE : bool = false $($(| as_true!($err_guard))*)*;
type CaughtErrors = ($($($err_type,)*)*);
fn internal<Input : ::error_union::internal::GetErrorSet, OkType>(_ : &Result<OkType, ::error_union::internal::Error<Input>>)
{
struct Holder<A : ::error_union::internal::GetErrorSet,B : ::error_union::internal::GetErrorSet>(::std::marker::PhantomData<A>, ::std::marker::PhantomData<B>);
impl<A : ::error_union::internal::GetErrorSet,B : ::error_union::internal::GetErrorSet> Holder<A,B>
{
const ASSERT: bool = {
if let Some(msg) = ::error_union::internal::generate_msg_for_match_err::<A,B>(HAS_UNDERSCORE)
{
::error_union::internal::concat_panic(&[&msg.message])
} else {
false
}
};
}
if Holder::<Input, CaughtErrors>::ASSERT
{
unreachable!();
}
}
let temp = $e;
internal(&temp);
match temp {
Ok($ok_ident) => { $ok_arm },
Err(error) =>
{
match error.1 {
$(
$(
<$err_type>::ERROR_ID => {
if ::std::any::TypeId::of::<$err_type>() == error.2.type_id()
{
if let Ok($err_i) = error.2.downcast::<$err_type>()
{
$err_arm
} else {
panic!("Failed to downcast despite type id match");
}
} else {
panic!("Error id matched in match err arm, but type id check failed");
}
}, )*
$(
_ => {
let $err_i = error.subtract_errors::<CaughtErrors>();
$err_guard
},)*
)*
_ => todo!(),
}
}
}
}
}