@@ -26,12 +26,6 @@ pub(crate) fn derive(node: &DeriveInput) -> Result<proc_macro2::TokenStream> {
2626 let metrics_attr = parse_metrics_attr ( node) ?;
2727 let metric_fields = parse_metric_fields ( node) ?;
2828
29- let describe_doc = quote ! {
30- /// Describe all exposed metrics. Internally calls `describe_*` macros from
31- /// the metrics crate according to the metric type.
32- ///
33- /// See <https://docs.rs/metrics/latest/metrics/index.html#macros>
34- } ;
3529 let register_and_describe = match & metrics_attr. scope {
3630 MetricsScope :: Static ( scope) => {
3731 let ( field_inits, describes) : ( Vec < _ > , Vec < _ > ) = metric_fields
@@ -93,31 +87,25 @@ pub(crate) fn derive(node: &DeriveInput) -> Result<proc_macro2::TokenStream> {
9387
9488 quote ! {
9589 impl Default for #ty {
96- fn default ( ) -> Self {
97- Self :: new( )
98- }
99- }
100-
101- impl #ty {
10290 /// Creates a new instance of the metrics.
10391 ///
10492 /// This initializes all metrics and registers them with the global recorder.
105- /// Metrics are described and registered only once; subsequent calls return
106- /// a clone of the initially registered metrics.
107- ///
108- /// To re-register or register with labels, use [`Self::new_with_labels`].
109- #vis fn new( ) -> Self {
110- static __REGISTER_ONCE: :: std:: sync:: OnceLock <#ty> = :: std:: sync:: OnceLock :: new( ) ;
111- __REGISTER_ONCE. get_or_init( || {
112- Self :: new_with_labels( :: std:: vec:: Vec :: <:: metrics:: Label >:: new( ) )
113- } ) . _clone( )
93+ /// Metrics are described only once; see [`Self::describe`].
94+ fn default ( ) -> Self {
95+ Self :: _new_with_labels( :: std:: vec:: Vec :: <:: metrics:: Label >:: new( ) )
11496 }
97+ }
11598
99+ impl #ty {
116100 /// Creates a new instance of the metrics with the provided labels.
117101 ///
118- /// Unlike [`Self::new `], this does not cache the result, so it can be used
102+ /// Unlike [`Self::default `], this does not cache the result, so it can be used
119103 /// to re-register metrics or register with different labels.
120- #vis fn new_with_labels( labels: impl :: metrics:: IntoLabels + Clone ) -> Self {
104+ #vis fn new_with_labels( labels: impl :: metrics:: IntoLabels ) -> Self {
105+ Self :: _new_with_labels( labels. into_labels( ) )
106+ }
107+
108+ fn _new_with_labels( labels: :: std:: vec:: Vec <:: metrics:: Label >) -> Self {
121109 Self :: describe( ) ;
122110 :: metrics:: with_recorder( |__recorder| {
123111 static __METADATA: :: metrics:: Metadata <' static > = :: metrics:: Metadata :: new(
@@ -133,13 +121,24 @@ pub(crate) fn derive(node: &DeriveInput) -> Result<proc_macro2::TokenStream> {
133121 } )
134122 }
135123
136- #describe_doc
124+ /// Describe all exposed metrics.
125+ ///
126+ /// Internally, this calls the `describe_*` macros from the metrics crate
127+ /// according to the metric type.
128+ ///
129+ /// This is done only once, to avoid multiple `describe` calls to the same
130+ /// recorder. If this is not preferred, you can call [`Self::force_describe`]
131+ /// directly.
132+ ///
133+ /// See: <https://docs.rs/metrics/latest/metrics/index.html#macros>
137134 #vis fn describe( ) {
138135 static __DESCRIBE_ONCE: :: std:: sync:: Once = :: std:: sync:: Once :: new( ) ;
139136 __DESCRIBE_ONCE. call_once( Self :: force_describe) ;
140137 }
141138
142139 /// Unconditionally describes all metrics.
140+ ///
141+ /// See [`Self::describe`].
143142 #vis fn force_describe( ) {
144143 :: metrics:: with_recorder( |__recorder| {
145144 #( #describes) *
@@ -209,12 +208,15 @@ pub(crate) fn derive(node: &DeriveInput) -> Result<proc_macro2::TokenStream> {
209208 ///
210209 /// This initializes all metrics and registers them with the global recorder.
211210 #vis fn new( scope: & str ) -> Self {
212- Self :: describe( scope) ;
213- Self :: new_with_labels( scope, :: std:: vec:: Vec :: <:: metrics:: Label >:: new( ) )
211+ Self :: _new_with_labels( scope, :: std:: vec:: Vec :: <:: metrics:: Label >:: new( ) )
214212 }
215213
216214 /// Creates a new instance of the metrics with the provided scope and labels.
217- #vis fn new_with_labels( scope: & str , labels: impl :: metrics:: IntoLabels + Clone ) -> Self {
215+ #vis fn new_with_labels( scope: & str , labels: impl :: metrics:: IntoLabels ) -> Self {
216+ Self :: _new_with_labels( scope, labels. into_labels( ) )
217+ }
218+
219+ fn _new_with_labels( scope: & str , labels: :: std:: vec:: Vec <:: metrics:: Label >) -> Self {
218220 Self :: describe( scope) ;
219221 :: metrics:: with_recorder( |__recorder| {
220222 static __METADATA: :: metrics:: Metadata <' static > = :: metrics:: Metadata :: new(
@@ -231,7 +233,10 @@ pub(crate) fn derive(node: &DeriveInput) -> Result<proc_macro2::TokenStream> {
231233 } )
232234 }
233235
234- #describe_doc
236+ /// Describe all exposed metrics. Internally calls `describe_*` macros from
237+ /// the metrics crate according to the metric type.
238+ ///
239+ /// See: <https://docs.rs/metrics/latest/metrics/index.html#macros>
235240 #vis fn describe( scope: & str ) {
236241 :: metrics:: with_recorder( |__recorder| {
237242 let __scope = scope;
0 commit comments