pub struct ForwardedReply<M, R>
where
R: Reply,
{
inner: ForwardedReplyInner<M, R>,
}
enum ForwardedReplyInner<M, R>
where
R: Reply,
{
Forwarded(Result<(), SendError<M, R::Error>>),
Direct(Result<R::Ok, R::Error>),
}
impl<M, R> fmt::Debug for ForwardedReply<M, R>
where
M: fmt::Debug,
R: Reply,
R::Ok: fmt::Debug,
R::Error: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ForwardedReply")
.field("inner", &self.inner)
.finish()
}
}
impl<M, R> fmt::Debug for ForwardedReplyInner<M, R>
where
M: fmt::Debug,
R: Reply,
R::Ok: fmt::Debug,
R::Error: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Forwarded(res) => f.debug_tuple("Forwarded").field(res).finish(),
Self::Direct(res) => f.debug_tuple("Direct").field(res).finish(),
}
}
}
impl<M, R> ForwardedReply<M, R>
where
R: Reply,
{
pub(crate) fn new(res: Result<(), SendError<M, R::Error>>) -> Self {
ForwardedReply {
inner: ForwardedReplyInner::Forwarded(res),
}
}
pub fn from_ok(value: R::Ok) -> Self {
ForwardedReply {
inner: ForwardedReplyInner::Direct(Ok(value)),
}
}
pub fn from_err(error: R::Error) -> Self {
ForwardedReply {
inner: ForwardedReplyInner::Direct(Err(error)),
}
}
pub fn from_result(result: Result<R::Ok, R::Error>) -> Self {
ForwardedReply {
inner: ForwardedReplyInner::Direct(result),
}
}
}
impl<M, R> Reply for ForwardedReply<M, R>
where
R: Reply,
M: Send + 'static,
{
type Ok = R::Ok;
type Error = SendError<M, R::Error>;
type Value = Result<Self::Ok, Self::Error>;
fn to_result(self) -> Result<Self::Ok, Self::Error> {
match self.inner {
ForwardedReplyInner::Forwarded(res) => res.map(|_| {
unreachable!("forwarded reply is only converted to a result if its an error")
}),
ForwardedReplyInner::Direct(result) => {
result.map_err(SendError::<M, R::Error>::HandlerError)
}
}
}
fn into_any_err(self) -> Option<Box<dyn ReplyError>> {
match self.inner {
ForwardedReplyInner::Forwarded(res) => {
res.err().map(|err| Box::new(err) as Box<dyn ReplyError>)
}
ForwardedReplyInner::Direct(result) => result.err().map(|err| {
Box::new(SendError::<M, R::Error>::HandlerError(err)) as Box<dyn ReplyError>
}),
}
}
fn into_value(self) -> Self::Value {
match self.inner {
ForwardedReplyInner::Forwarded(res) => res.map(|_| {
unreachable!("forwarded reply is only an error if it failed to forward the message")
}),
ForwardedReplyInner::Direct(result) => {
result.map_err(SendError::<M, R::Error>::HandlerError)
}
}
}
fn downcast_ok(ok: Box<dyn any::Any>) -> Self::Ok {
*ok.downcast().unwrap()
}
fn downcast_err<N: 'static>(err: BoxSendError) -> SendError<N, Self::Error> {
err.try_downcast::<N, R::Error>()
.map(|err| err.map_err(SendError::HandlerError))
.unwrap_or_else(|err| {
err.downcast::<M, SendError<M, R::Error>>().map_msg(|_| {
unreachable!(
"forwarded reply is only an error if it failed to forward the message"
)
})
})
}
}