From e8724e4df3b112fe75ca32c634d3707ec4ba56a4 Mon Sep 17 00:00:00 2001 From: Dominik Werder Date: Fri, 4 Apr 2025 18:33:29 +0200 Subject: [PATCH] Aggregation from Metrics --- src/log.rs | 6 ++++ src/make_metrics.rs | 7 +++- src/make_metrics/codegen.rs | 66 ++++++++++++++++++++++++++++++++----- src/make_metrics/resolve.rs | 5 +++ 4 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 src/make_metrics/resolve.rs diff --git a/src/log.rs b/src/log.rs index c0ac7e7..acb5fea 100644 --- a/src/log.rs +++ b/src/log.rs @@ -1,3 +1,4 @@ +use proc_macro2::TokenStream; use std::fs::File; use std::io::Write; use std::sync::Mutex; @@ -20,3 +21,8 @@ pub fn log(s: &str) { fout.write(&buf).unwrap(); *mg = Some(fout); } + +pub fn log_ts(ts: &TokenStream) { + let fmtd = prettyplease::unparse(&syn::parse2::(ts.clone()).unwrap()); + log(&fmtd); +} diff --git a/src/make_metrics.rs b/src/make_metrics.rs index 6662794..735a94a 100644 --- a/src/make_metrics.rs +++ b/src/make_metrics.rs @@ -1,4 +1,5 @@ mod codegen; +mod resolve; use crate::log::log; use proc_macro2::Span; @@ -249,6 +250,8 @@ struct MetricsModItem { compose_mods: Vec, } +impl MetricsModItem {} + impl syn::parse::Parse for MetricsModItem { fn parse(inp: ParseStream) -> syn::Result { let mut struct_name = None; @@ -510,7 +513,9 @@ pub(super) fn make_metrics(ts: proc_macro::TokenStream) -> proc_macro::TokenStre log(&format!("call_site {:?}", Span::call_site())); log(&manifest_dir); let ts5 = proc_macro::TokenStream::from(ts4); - let decls_file = syn::parse_macro_input!(ts5 as MetricsDecl); + let mut decls_file = syn::parse_macro_input!(ts5 as MetricsDecl); + decls_file.resolve(); + let decls_file = decls_file; let s1 = decls_file.to_inspect(); let ts_out = decls_file.to_code().unwrap(); let fmtd = prettyplease::unparse(&syn::parse2::(ts_out.clone()).unwrap()); diff --git a/src/make_metrics/codegen.rs b/src/make_metrics/codegen.rs index 8b54c04..939adb1 100644 --- a/src/make_metrics/codegen.rs +++ b/src/make_metrics/codegen.rs @@ -1,7 +1,8 @@ +use super::AggregationModItem; +use super::MetricsDecl; +use super::MetricsModItem; use crate::log::log; -use crate::make_metrics::AggregationModItem; -use crate::make_metrics::MetricsDecl; -use crate::make_metrics::MetricsModItem; +use crate::log::log_ts; use proc_macro2::Span; use proc_macro2::TokenStream; @@ -32,38 +33,81 @@ impl MetricsDecl { (fields_decl, fields_init, ingest_counters) }; - let _ = { + let (fields_compose_decl, fields_compose_init, ingest_compose) = { + let mut fields_decl = Vec::new(); + let mut fields_init = Vec::new(); + let mut ingest = Vec::new(); for cm1 in inp.compose_mods.iter() { log(&format!( "agg_from_metrics_token_stream mod Compose cm {:?}", cm1 )); + let mut found = false; for cm2 in agg.compose_agg_mods.iter() { if cm2.input == cm1.name { + if found { + let e = syn::Error::new( + Span::call_site(), + format!( + "found composition method for input Compose again {:?} {:?}", + cm1, cm2 + ), + ); + return Err(e); + } log(&format!( "agg_from_metrics_token_stream found pair cm1 {:?} cm2 {:?}", cm1, cm2 )); + // TODO difference? + let _name1 = quote::format_ident!("{}", cm1.name); + let name1 = syn::Ident::new(&cm1.name, Span::call_site()); + let name2 = syn::Ident::new(&cm2.name, Span::call_site()); + let aggtor = syn::Ident::new(&cm2.aggtor, Span::call_site()); + let ts = quote::quote! { #name2: #aggtor, }; + fields_decl.push(ts); + let ts = quote::quote! { #name2: <#aggtor>::new(), }; + fields_init.push(ts); + let ts = quote::quote! { + // let _ = &inp.#name1; + self.#name2.ingest(inp.#name1); + }; + ingest.push(ts); + found = true; } } + if found == false { + let e = syn::Error::new( + Span::call_site(), + format!( + "did not find composition method for input Compose {:?}", + cm1 + ), + ); + return Err(e); + } } + (fields_decl, fields_init, ingest) }; let ret = quote::quote! { #[derive(Debug)] pub struct #struct_name { #(#fields_counters_decl)* + #(#fields_compose_decl)* } impl #struct_name { pub fn new() -> Self { Self { #(#fields_counters_init)* + #(#fields_compose_init)* } } pub fn ingest(&mut self, inp: #inp_struct_name) { #(#ingest_counters)* + #(#ingest_compose)* } } }; @@ -104,8 +148,7 @@ impl MetricsDecl { } fn agg_token_stream(&self, agg: &AggregationModItem) -> syn::Result { - // Input can be a Metrics or a Aggregation type. - if let Some(inp) = self + let ts1 = if let Some(inp) = self .metrics_mods .iter() .filter(|&x| x.struct_name == agg.input) @@ -128,7 +171,13 @@ impl MetricsDecl { ), ); Err(e) - } + }; + let ts1 = ts1?; + let ret = quote::quote! { + #ts1 + }; + log_ts(&ret); + Ok(ret) } fn agg_all_token_stream(&self) -> syn::Result { @@ -178,7 +227,7 @@ impl MetricsDecl { .map(|x| syn::Ident::new(x, Span::call_site())) .map(|x| { quote::quote! { - #[inline(always)] + // #[inline(always)] pub fn #x(&mut self) -> &mut CounterU32 { &mut self.#x } @@ -193,6 +242,7 @@ impl MetricsDecl { let n = syn::Ident::new(&m.name, Span::call_site()); let ct = syn::Ident::new(&m.input, Span::call_site()); quote::quote! { + // #[inline(always)] pub fn #n(&mut self) -> &mut #ct { &mut self.#n } diff --git a/src/make_metrics/resolve.rs b/src/make_metrics/resolve.rs new file mode 100644 index 0000000..f46282f --- /dev/null +++ b/src/make_metrics/resolve.rs @@ -0,0 +1,5 @@ +use super::MetricsDecl; + +impl MetricsDecl { + pub(super) fn resolve(&mut self) {} +}