use super::{Error, Input, InterceptorContext, Output};
use crate::client::interceptors::context::{Request, Response};
use crate::client::orchestrator::OrchestratorError;
use std::fmt::Debug;
macro_rules! output {
(&Option<Result<$o_ty:ty, $e_ty:ty>>) => {
Option<Result<&$o_ty, &$e_ty>>
};
(&Option<$ty:ty>) => {
Option<&$ty>
};
(&mut Option<$ty:ty>) => {
Option<&mut $ty>
};
(&Result<$o_ty:ty, $e_ty:ty>) => {
Result<&$o_ty, &$e_ty>
};
(&$($tt:tt)+) => {
&$($tt)+
};
(&mut $($tt:tt)+) => {
&mut $($tt)+
};
}
macro_rules! declare_method {
(&mut $name:ident, $inner_name:ident, $doc:literal, Option<$ty:ty>) => {
#[doc=$doc]
pub fn $name(&mut self) -> Option<&mut $ty> {
self.inner.$inner_name.as_ref()
}
};
(&$name:ident, $inner_name:ident, $doc:literal, Option<$ty:ty>) => {
#[doc=$doc]
pub fn $name(&self) -> Option<$ty> {
self.inner.$inner_name.as_mut()
}
};
(&mut $name:ident, $doc:literal, $($tt:tt)+) => {
#[doc=$doc]
pub fn $name(&mut self) -> output!(&mut $($tt)+) {
self.inner.$name()
}
};
(&$name:ident, $doc:literal, $($tt:tt)+) => {
#[doc=$doc]
pub fn $name(&self) -> output!(&$($tt)+) {
self.inner.$name()
}
};
}
macro_rules! declare_known_method {
(output_or_error: &mut $($tt:tt)+) => {
declare_method!(&mut output_or_error_mut, "Returns a mutable reference to the deserialized output or error.", $($tt)+);
};
(output_or_error: &$($tt:tt)+) => {
declare_method!(&output_or_error, "Returns a reference to the deserialized output or error.", $($tt)+);
};
(input: &mut $($tt:tt)+) => {
declare_method!(&mut input_mut, "Returns a mutable reference to the input.", $($tt)+);
};
(input: &$($tt:tt)+) => {
declare_method!(&input, "Returns a reference to the input.", $($tt)+);
};
(request: &mut $($tt:tt)+) => {
declare_method!(&mut request_mut, "Returns a mutable reference to the transmittable request for the operation being invoked.", $($tt)+);
};
(request: &$($tt:tt)+) => {
declare_method!(&request, "Returns a reference to the transmittable request for the operation being invoked.", $($tt)+);
};
(response: &mut $($tt:tt)+) => {
declare_method!(&mut response_mut, "Returns a mutable reference to the response.", $($tt)+);
};
(response: &$($tt:tt)+) => {
declare_method!(&response, "Returns a reference to the response.", $($tt)+);
};
}
macro_rules! declare_wrapper {
(($ref_struct_name:ident $mut_struct_name:ident)$($tt:tt)+) => {
pub struct $ref_struct_name<'a, I = Input, O = Output, E = Error>
where E: Debug {
inner: &'a InterceptorContext<I, O, E>,
}
impl<'a, I, O, E: Debug> From<&'a InterceptorContext<I, O, E>> for $ref_struct_name<'a, I, O, E>
{
fn from(inner: &'a InterceptorContext<I, O, E>) -> Self {
Self { inner }
}
}
impl<'a, I, O, E: Debug> $ref_struct_name<'a, I, O, E> {
declare_ref_wrapper_methods!($($tt)+);
}
pub struct $mut_struct_name<'a, I = Input, O = Output, E = Error>
where E: Debug {
inner: &'a mut InterceptorContext<I, O, E>,
}
impl<'a, I, O, E: Debug> From<&'a mut InterceptorContext<I, O, E>> for $mut_struct_name<'a, I, O, E>
{
fn from(inner: &'a mut InterceptorContext<I, O, E>) -> Self {
Self { inner }
}
}
impl<'a, I, O, E: Debug> $mut_struct_name<'a, I, O, E> {
declare_ref_wrapper_methods!($($tt)+);
declare_mut_wrapper_methods!($($tt)+);
}
};
}
macro_rules! declare_ref_wrapper_methods {
(($field:ident: $($head:tt)+)$($tail:tt)+) => {
declare_known_method!($field: &$($head)+);
declare_ref_wrapper_methods!($($tail)+);
};
(($field:ident: $($tt:tt)+)) => {
declare_known_method!($field: &$($tt)+);
};
}
macro_rules! declare_mut_wrapper_methods {
(($field:ident: $($head:tt)+)$($tail:tt)+) => {
declare_known_method!($field: &mut $($head)+);
declare_mut_wrapper_methods!($($tail)+);
};
(($field:ident: $($tt:tt)+)) => {
declare_known_method!($field: &mut $($tt)+);
};
}
declare_wrapper!(
(BeforeSerializationInterceptorContextRef BeforeSerializationInterceptorContextMut)
(input: I)
);
declare_wrapper!(
(BeforeTransmitInterceptorContextRef BeforeTransmitInterceptorContextMut)
(input: I)
(request: Request)
);
declare_wrapper!(
(BeforeDeserializationInterceptorContextRef BeforeDeserializationInterceptorContextMut)
(input: I)
(request: Request)
(response: Response)
);
declare_wrapper!(
(AfterDeserializationInterceptorContextRef AfterDeserializationInterceptorContextMut)
(input: I)
(request: Request)
(response: Response)
(output_or_error: Result<O, OrchestratorError<E>>)
);
pub struct FinalizerInterceptorContextRef<'a, I = Input, O = Output, E = Error>
where
E: Debug,
{
inner: &'a InterceptorContext<I, O, E>,
}
impl<'a, I, O, E: Debug> From<&'a InterceptorContext<I, O, E>>
for FinalizerInterceptorContextRef<'a, I, O, E>
{
fn from(inner: &'a InterceptorContext<I, O, E>) -> Self {
Self { inner }
}
}
impl<'a, I, O, E: Debug> FinalizerInterceptorContextRef<'a, I, O, E> {
pub fn input(&self) -> Option<&I> {
self.inner.input.as_ref()
}
pub fn request(&self) -> Option<&Request> {
self.inner.request.as_ref()
}
pub fn response(&self) -> Option<&Response> {
self.inner.response.as_ref()
}
pub fn output_or_error(&self) -> Option<Result<&O, &OrchestratorError<E>>> {
self.inner.output_or_error.as_ref().map(|o| o.as_ref())
}
}
pub struct FinalizerInterceptorContextMut<'a, I = Input, O = Output, E = Error>
where
E: Debug,
{
inner: &'a mut InterceptorContext<I, O, E>,
}
impl<'a, I, O, E: Debug> From<&'a mut InterceptorContext<I, O, E>>
for FinalizerInterceptorContextMut<'a, I, O, E>
{
fn from(inner: &'a mut InterceptorContext<I, O, E>) -> Self {
Self { inner }
}
}
impl<'a, I, O, E: Debug> FinalizerInterceptorContextMut<'a, I, O, E> {
pub fn input(&self) -> Option<&I> {
self.inner.input.as_ref()
}
pub fn request(&self) -> Option<&Request> {
self.inner.request.as_ref()
}
pub fn response(&self) -> Option<&Response> {
self.inner.response.as_ref()
}
pub fn output_or_error(&self) -> Option<Result<&O, &OrchestratorError<E>>> {
self.inner.output_or_error.as_ref().map(|o| o.as_ref())
}
pub fn input_mut(&mut self) -> Option<&mut I> {
self.inner.input.as_mut()
}
pub fn request_mut(&mut self) -> Option<&mut Request> {
self.inner.request.as_mut()
}
pub fn response_mut(&mut self) -> Option<&mut Response> {
self.inner.response.as_mut()
}
pub fn output_or_error_mut(&mut self) -> Option<&mut Result<O, OrchestratorError<E>>> {
self.inner.output_or_error.as_mut()
}
}