in quic/s2n-quic-events/src/parser.rs [99:411]
fn to_tokens(&self, output: &mut Output) {
let Self {
attrs,
ident,
generics,
fields,
} = self;
let ident_str = ident.to_string();
let derive_attrs = &attrs.derive_attrs;
let builder_derive_attrs = &attrs.builder_derive_attrs;
let extra_attrs = &attrs.extra;
let deprecated = &attrs.deprecated;
let allow_deprecated = &attrs.allow_deprecated;
let destructure_fields: Vec<_> = fields.iter().map(Field::destructure).collect();
let builder_fields = fields.iter().map(Field::builder);
let builder_field_impls = fields.iter().map(Field::builder_impl);
let api_fields = fields.iter().map(Field::api);
let snapshot_fields = fields.iter().map(Field::snapshot);
if attrs.builder_derive {
output.builders.extend(quote!(
#[#builder_derive_attrs]
));
}
output.builders.extend(quote!(
#[derive(Clone, Debug)]
#extra_attrs
pub struct #ident #generics {
#(#builder_fields)*
}
#allow_deprecated
impl #generics IntoEvent<api::#ident #generics> for #ident #generics {
#[inline]
fn into_event(self) -> api::#ident #generics {
let #ident {
#(#destructure_fields),*
} = self;
api::#ident {
#(#builder_field_impls)*
}
}
}
));
if attrs.derive {
output.api.extend(quote!(#[derive(Clone, Debug)]));
}
if !attrs.exhaustive {
output.api.extend(quote!(#[non_exhaustive]));
}
output.api.extend(quote!(
#derive_attrs
#extra_attrs
#deprecated
#allow_deprecated
pub struct #ident #generics {
#(#api_fields)*
}
#[cfg(any(test, feature = "testing"))]
#allow_deprecated
impl #generics crate::event::snapshot::Fmt for #ident #generics {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
let mut fmt = fmt.debug_struct(#ident_str);
#(#snapshot_fields)*
fmt.finish()
}
}
));
if let Some(event_name) = attrs.event_name.as_ref() {
output.api.extend(quote!(
#allow_deprecated
impl #generics Event for #ident #generics {
const NAME: &'static str = #event_name;
}
));
let ident_str = self.ident_str();
let snake = self.ident_snake();
let counter = self.counter();
let function = self.function();
let subscriber_doc = format!("Called when the `{ident_str}` event is triggered");
let publisher_doc =
format!("Publishes a `{ident_str}` event to the publisher's subscriber");
let counter_type = output.mode.counter_type();
let counter_init = output.mode.counter_init();
// add a counter for testing structs
output.testing_fields.extend(quote!(
pub #counter: #counter_type,
));
output.testing_fields_init.extend(quote!(
#counter: #counter_init,
));
let receiver = output.mode.receiver();
let counter_increment = output.mode.counter_increment();
let lock = output.mode.lock();
match attrs.subject {
Subject::Endpoint => {
output.subscriber.extend(quote!(
#[doc = #subscriber_doc]
#[inline]
#deprecated
#allow_deprecated
fn #function(&#receiver self, meta: &api::EndpointMeta, event: &api::#ident) {
let _ = meta;
let _ = event;
}
));
output.tuple_subscriber.extend(quote!(
#[inline]
#allow_deprecated
fn #function(&#receiver self, meta: &api::EndpointMeta, event: &api::#ident) {
(self.0).#function(meta, event);
(self.1).#function(meta, event);
}
));
if output.mode.is_ref() {
output.ref_subscriber.extend(quote!(
#[inline]
#allow_deprecated
fn #function(&#receiver self, meta: &api::EndpointMeta, event: &api::#ident) {
self.as_ref().#function(meta, event);
}
));
}
output.tracing_subscriber.extend(quote!(
#[inline]
#allow_deprecated
fn #function(&#receiver self, meta: &api::EndpointMeta, event: &api::#ident) {
let parent = self.parent(meta);
let api::#ident { #(#destructure_fields),* } = event;
tracing::event!(target: #snake, parent: parent, tracing::Level::DEBUG, { #(#destructure_fields = tracing::field::debug(#destructure_fields)),* });
}
));
output.endpoint_publisher.extend(quote!(
#[doc = #publisher_doc]
fn #function(&#receiver self, event: builder::#ident);
));
output.endpoint_publisher_subscriber.extend(quote!(
#[inline]
#allow_deprecated
fn #function(&#receiver self, event: builder::#ident) {
let event = event.into_event();
self.subscriber.#function(&self.meta, &event);
self.subscriber.on_event(&self.meta, &event);
}
));
for subscriber in [
&mut output.endpoint_subscriber_testing,
&mut output.subscriber_testing,
] {
subscriber.extend(quote!(
#allow_deprecated
fn #function(&#receiver self, meta: &api::EndpointMeta, event: &api::#ident) {
self.#counter #counter_increment;
let meta = crate::event::snapshot::Fmt::to_snapshot(meta);
let event = crate::event::snapshot::Fmt::to_snapshot(event);
let out = format!("{meta:?} {event:?}");
self.output #lock.push(out);
}
));
}
// add a counter for testing structs
output.endpoint_testing_fields.extend(quote!(
pub #counter: #counter_type,
));
output.endpoint_testing_fields_init.extend(quote!(
#counter: #counter_init,
));
output.endpoint_publisher_testing.extend(quote!(
#allow_deprecated
fn #function(&#receiver self, event: builder::#ident) {
self.#counter #counter_increment;
let event = event.into_event();
let event = crate::event::snapshot::Fmt::to_snapshot(&event);
let out = format!("{event:?}");
self.output #lock.push(out);
}
));
}
Subject::Connection => {
output.subscriber.extend(quote!(
#[doc = #subscriber_doc]
#[inline]
#deprecated
#allow_deprecated
fn #function(
&#receiver self,
context: &#receiver Self::ConnectionContext,
meta: &api::ConnectionMeta,
event: &api::#ident
) {
let _ = context;
let _ = meta;
let _ = event;
}
));
output.tuple_subscriber.extend(quote!(
#[inline]
#allow_deprecated
fn #function(
&#receiver self,
context: &#receiver Self::ConnectionContext,
meta: &api::ConnectionMeta,
event: &api::#ident
) {
(self.0).#function(&#receiver context.0, meta, event);
(self.1).#function(&#receiver context.1, meta, event);
}
));
if output.mode.is_ref() {
output.ref_subscriber.extend(quote!(
#[inline]
#allow_deprecated
fn #function(
&#receiver self,
context: &#receiver Self::ConnectionContext,
meta: &api::ConnectionMeta,
event: &api::#ident
) {
self.as_ref().#function(context, meta, event);
}
));
}
output.tracing_subscriber.extend(quote!(
#[inline]
#allow_deprecated
fn #function(
&#receiver self,
context: &#receiver Self::ConnectionContext,
_meta: &api::ConnectionMeta,
event: &api::#ident
) {
let id = context.id();
let api::#ident { #(#destructure_fields),* } = event;
tracing::event!(target: #snake, parent: id, tracing::Level::DEBUG, { #(#destructure_fields = tracing::field::debug(#destructure_fields)),* });
}
));
output.connection_publisher.extend(quote!(
#[doc = #publisher_doc]
fn #function(&#receiver self, event: builder::#ident);
));
output.connection_publisher_subscriber.extend(quote!(
#[inline]
#allow_deprecated
fn #function(&#receiver self, event: builder::#ident) {
let event = event.into_event();
self.subscriber.#function(self.context, &self.meta, &event);
self.subscriber.on_connection_event(self.context, &self.meta, &event);
self.subscriber.on_event(&self.meta, &event);
}
));
output.subscriber_testing.extend(quote!(
#allow_deprecated
fn #function(
&#receiver self,
_context: &#receiver Self::ConnectionContext,
meta: &api::ConnectionMeta,
event: &api::#ident
) {
self.#counter #counter_increment;
if self.location.is_some() {
let meta = crate::event::snapshot::Fmt::to_snapshot(meta);
let event = crate::event::snapshot::Fmt::to_snapshot(event);
let out = format!("{meta:?} {event:?}");
self.output #lock.push(out);
}
}
));
output.connection_publisher_testing.extend(quote!(
#allow_deprecated
fn #function(&#receiver self, event: builder::#ident) {
self.#counter #counter_increment;
let event = event.into_event();
if self.location.is_some() {
let event = crate::event::snapshot::Fmt::to_snapshot(&event);
let out = format!("{event:?}");
self.output #lock.push(out);
}
}
));
}
}
}
}