use quote::quote;
use syn::Result;
use super::*;
pub(crate) fn impl_channels_out_struct(info: &OrchestraInfo) -> Result<proc_macro2::TokenStream> {
let message_wrapper = info.message_wrapper.clone();
let channel_name = &info.channel_names_without_wip(None);
let channel_name_unbounded = &info.channel_names_without_wip("_unbounded");
let maybe_boxed_consumes = info
.consumes_without_wip()
.iter()
.map(|consume| info.box_message_if_needed(consume, Span::call_site()))
.collect::<Vec<_>>();
let maybe_boxed_send = if info.boxed_messages {
quote! { ::std::boxed::Box::new(inner) }
} else {
quote! { inner }
};
let maybe_unbox_error = if info.boxed_messages {
quote! { *err_inner.message }
} else {
quote! { err_inner.message }
};
let consumes_variant = &info.variant_names_without_wip();
let unconsumes_variant = &info.variant_names_only_wip();
let feature_gates = info.feature_gates();
let support_crate = info.support_crate_name();
let ts = quote! {
#[derive(Debug, Clone)]
pub struct ChannelsOut {
#(
#feature_gates
pub #channel_name:
#support_crate ::metered::MeteredSender<
MessagePacket< #maybe_boxed_consumes >
>,
)*
#(
#feature_gates
pub #channel_name_unbounded:
#support_crate ::metered::UnboundedMeteredSender<
MessagePacket< #maybe_boxed_consumes >
>,
)*
}
#[allow(unreachable_code)]
impl ChannelsOut {
pub async fn send_and_log_error<P: #support_crate ::Priority>(
&mut self,
signals_received: usize,
message: #message_wrapper
) {
let res: ::std::result::Result<_, _> = match message {
#(
#feature_gates
#message_wrapper :: #consumes_variant ( inner ) => {
match P::priority() {
#support_crate ::PriorityLevel::Normal => {
self. #channel_name .send(
#support_crate ::make_packet(signals_received, #maybe_boxed_send)
).await
},
#support_crate ::PriorityLevel::High => {
self. #channel_name .priority_send(
#support_crate ::make_packet(signals_received, #maybe_boxed_send)
).await
},
}.map_err(|_| stringify!( #channel_name ))
}
)*
#(
#message_wrapper :: #unconsumes_variant ( _ ) => Ok(()),
)*
#message_wrapper :: Empty => Ok(()),
#[allow(unreachable_patterns)]
unused_msg => {
#support_crate :: tracing :: warn!("Nothing consumes {:?}", unused_msg);
Ok(())
}
};
if let Err(subsystem_name) = res {
#support_crate ::tracing::debug!(
target: LOG_TARGET,
"Failed to send (bounded) a message to {} subsystem",
subsystem_name
);
}
}
pub fn try_send<P: #support_crate ::Priority>(
&mut self,
signals_received: usize,
message: #message_wrapper,
) -> ::std::result::Result<(), #support_crate ::metered::TrySendError<#message_wrapper>> {
let res: ::std::result::Result<_, _> = match message {
#(
#feature_gates
#message_wrapper :: #consumes_variant ( inner ) => {
match P::priority() {
#support_crate ::PriorityLevel::Normal => {
self. #channel_name .try_send(
#support_crate ::make_packet(signals_received, #maybe_boxed_send)
)
},
#support_crate ::PriorityLevel::High => {
self. #channel_name .try_priority_send(
#support_crate ::make_packet(signals_received, #maybe_boxed_send)
)
},
}.map_err(|err| match err {
#support_crate ::metered::TrySendError::Full(err_inner) => #support_crate ::metered::TrySendError::Full(#message_wrapper:: #consumes_variant ( #maybe_unbox_error )),
#support_crate ::metered::TrySendError::Closed(err_inner) => #support_crate ::metered::TrySendError::Closed(#message_wrapper:: #consumes_variant ( #maybe_unbox_error )),
})
}
)*
#(
#message_wrapper :: #unconsumes_variant ( _ ) => Ok(()),
)*
#message_wrapper :: Empty => Ok(()),
#[allow(unreachable_patterns)]
unused_msg => {
#support_crate :: tracing :: warn!("Nothing consumes {:?}", unused_msg);
Ok(())
}
};
res
}
pub fn send_unbounded_and_log_error(
&self,
signals_received: usize,
message: #message_wrapper,
) {
let res: ::std::result::Result<_, _> = match message {
#(
#feature_gates
#message_wrapper :: #consumes_variant (inner) => {
self. #channel_name_unbounded .unbounded_send(
#support_crate ::make_packet(signals_received, #maybe_boxed_send)
)
.map_err(|_| stringify!( #channel_name ))
},
)*
#(
#message_wrapper :: #unconsumes_variant ( _ ) => Ok(()),
)*
#message_wrapper :: Empty => Ok(()),
#[allow(unreachable_patterns)]
unused_msg => {
#support_crate :: tracing :: warn!("Nothing consumes {:?}", unused_msg);
Ok(())
}
};
if let Err(subsystem_name) = res {
#support_crate ::tracing::debug!(
target: LOG_TARGET,
"Failed to send_unbounded a message to {} subsystem",
subsystem_name
);
}
}
}
};
Ok(ts)
}