Skip to main content

emit_macros/
lib.rs

1/*!
2Implementation details for `emit!` macros.
3
4This crate is not intended to be consumed directly.
5*/
6
7/*
8# Organization
9
10This crate contains the proc-macros that are exported in the `emit` crate. It expands to code that uses the `emit::__private` API, in particular the `emit::macro_hooks` module.
11
12# Hooks
13
14Code is transformed through _hooks_. A hook is a well-known method call, like `a.__private_emit_capture_as_default()`. The behavior of the hook is defined in `emit::macro_hooks`. Attribute macros look for these hooks and replace them to change behavior. For example, `#[emit::as_debug]` looks for any `__private_emit_capture_as_*` method and replaces it with `__private_emit_capture_as_debug`.
15
16# Testing
17
18Tests for this project mostly live in the top-level `test/ui` crate.
19*/
20
21#![deny(missing_docs)]
22#![doc(html_logo_url = "https://raw.githubusercontent.com/emit-rs/emit/main/asset/logo.svg")]
23
24extern crate proc_macro;
25
26#[macro_use]
27extern crate quote;
28
29#[macro_use]
30extern crate syn;
31
32use std::collections::HashMap;
33
34use proc_macro2::TokenStream;
35
36mod args;
37mod build;
38mod capture;
39mod dbg;
40mod emit;
41mod fmt;
42mod format;
43mod hook;
44mod key;
45mod optional;
46mod props;
47mod sample;
48mod span;
49mod template;
50mod util;
51
52use util::ResultToTokens;
53
54/**
55The set of hooks defined as a map.
56
57Hooks are regular attribute macros, but will be eagerly applied when expanding other macros to avoid the nightly-only feature that allows attribute macros on expressions. The `hook::eval_hooks` function will do this expansion.
58*/
59fn hooks() -> HashMap<&'static str, fn(TokenStream, TokenStream) -> syn::Result<TokenStream>> {
60    let mut map = HashMap::new();
61
62    map.insert(
63        "fmt",
64        (|args: TokenStream, expr: TokenStream| {
65            fmt::rename_hook_tokens(fmt::RenameHookTokens { args, expr })
66        }) as fn(TokenStream, TokenStream) -> syn::Result<TokenStream>,
67    );
68
69    map.insert(
70        "key",
71        (|args: TokenStream, expr: TokenStream| {
72            key::rename_hook_tokens(key::RenameHookTokens { args, expr })
73        }) as fn(TokenStream, TokenStream) -> syn::Result<TokenStream>,
74    );
75
76    map.insert(
77        "optional",
78        (|args: TokenStream, expr: TokenStream| {
79            optional::rename_hook_tokens(optional::RenameHookTokens { args, expr })
80        }) as fn(TokenStream, TokenStream) -> syn::Result<TokenStream>,
81    );
82
83    map.insert(
84        "as_value",
85        (|args: TokenStream, expr: TokenStream| {
86            capture_as(
87                "as_value",
88                args,
89                expr,
90                quote!(__private_capture_as_value),
91                quote!(__private_capture_anon_as_value),
92            )
93        }) as fn(TokenStream, TokenStream) -> syn::Result<TokenStream>,
94    );
95
96    map.insert(
97        "as_debug",
98        (|args: TokenStream, expr: TokenStream| {
99            capture_as(
100                "as_debug",
101                args,
102                expr,
103                quote!(__private_capture_as_debug),
104                quote!(__private_capture_anon_as_debug),
105            )
106        }) as fn(TokenStream, TokenStream) -> syn::Result<TokenStream>,
107    );
108
109    map.insert(
110        "as_display",
111        (|args: TokenStream, expr: TokenStream| {
112            capture_as(
113                "as_display",
114                args,
115                expr,
116                quote!(__private_capture_as_display),
117                quote!(__private_capture_anon_as_display),
118            )
119        }) as fn(TokenStream, TokenStream) -> syn::Result<TokenStream>,
120    );
121
122    map.insert(
123        "as_sval",
124        (|args: TokenStream, expr: TokenStream| {
125            #[cfg(feature = "sval")]
126            {
127                capture_as(
128                    "as_sval",
129                    args,
130                    expr,
131                    quote!(__private_capture_as_sval),
132                    quote!(__private_capture_anon_as_sval),
133                )
134            }
135            #[cfg(not(feature = "sval"))]
136            {
137                use syn::spanned::Spanned;
138
139                let _ = args;
140
141                Err(syn::Error::new(expr.span(), "capturing with `sval` is only possible when the `sval` Cargo feature is enabled"))
142            }
143        }) as fn(TokenStream, TokenStream) -> syn::Result<TokenStream>
144    );
145
146    map.insert(
147        "as_serde",
148        (|args: TokenStream, expr: TokenStream| {
149            #[cfg(feature = "serde")]
150            {
151                capture_as(
152                    "as_serde",
153                    args,
154                    expr,
155                    quote!(__private_capture_as_serde),
156                    quote!(__private_capture_anon_as_serde),
157                )
158            }
159            #[cfg(not(feature = "serde"))]
160            {
161                use syn::spanned::Spanned;
162
163                let _ = args;
164
165                Err(syn::Error::new(expr.span(), "capturing with `serde` is only possible when the `serde` Cargo feature is enabled"))
166            }
167        }) as fn(TokenStream, TokenStream) -> syn::Result<TokenStream>
168    );
169
170    map.insert(
171        "as_error",
172        (|args: TokenStream, expr: TokenStream| {
173            #[cfg(feature = "std")]
174            {
175                capture_as(
176                    "as_error",
177                    args,
178                    expr,
179                    quote!(__private_capture_as_error),
180                    quote!(__private_capture_as_error),
181                )
182            }
183            #[cfg(not(feature = "std"))]
184            {
185                use syn::spanned::Spanned;
186
187                let _ = args;
188
189                Err(syn::Error::new(
190                    expr.span(),
191                    "capturing errors is only possible when the `std` Cargo feature is enabled",
192                ))
193            }
194        }) as fn(TokenStream, TokenStream) -> syn::Result<TokenStream>,
195    );
196
197    map
198}
199
200#[doc = "Format a template."]
201#[doc = ""]
202#[doc = include_str!("./doc_fmt.md")]
203#[proc_macro]
204pub fn format(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
205    format::expand_tokens(format::ExpandTokens {
206        input: TokenStream::from(item),
207    })
208    .unwrap_or_compile_error()
209}
210
211#[doc = "Construct an event that can be emitted manually."]
212#[doc = ""]
213#[doc = include_str!("./doc_evt.md")]
214#[proc_macro]
215pub fn evt(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
216    build::expand_evt_tokens(build::ExpandEvtTokens {
217        level: None,
218        input: item.into(),
219    })
220    .unwrap_or_compile_error()
221}
222
223#[doc = "Construct an event at the debug level that can be emitted manually."]
224#[doc = ""]
225#[doc = include_str!("./doc_evt.md")]
226#[proc_macro]
227pub fn debug_evt(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
228    build::expand_evt_tokens(build::ExpandEvtTokens {
229        level: Some(quote!(emit::Level::Debug)),
230        input: item.into(),
231    })
232    .unwrap_or_compile_error()
233}
234
235#[doc = "Construct an event at the info level that can be emitted manually."]
236#[doc = ""]
237#[doc = include_str!("./doc_evt.md")]
238#[proc_macro]
239pub fn info_evt(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
240    build::expand_evt_tokens(build::ExpandEvtTokens {
241        level: Some(quote!(emit::Level::Info)),
242        input: item.into(),
243    })
244    .unwrap_or_compile_error()
245}
246
247#[doc = "Construct an event at the warn level that can be emitted manually."]
248#[doc = ""]
249#[doc = include_str!("./doc_evt.md")]
250#[proc_macro]
251pub fn warn_evt(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
252    build::expand_evt_tokens(build::ExpandEvtTokens {
253        level: Some(quote!(emit::Level::Warn)),
254        input: item.into(),
255    })
256    .unwrap_or_compile_error()
257}
258
259#[doc = "Construct an event at the error level that can be emitted manually."]
260#[doc = ""]
261#[doc = include_str!("./doc_evt.md")]
262#[proc_macro]
263pub fn error_evt(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
264    build::expand_evt_tokens(build::ExpandEvtTokens {
265        level: Some(quote!(emit::Level::Error)),
266        input: item.into(),
267    })
268    .unwrap_or_compile_error()
269}
270
271#[doc = "Trace the execution of a function."]
272#[doc = ""]
273#[doc = include_str!("./doc_span.md")]
274#[proc_macro_attribute]
275pub fn span(
276    args: proc_macro::TokenStream,
277    item: proc_macro::TokenStream,
278) -> proc_macro::TokenStream {
279    span::expand_tokens(span::ExpandTokens {
280        level: None,
281        input: TokenStream::from(args),
282        item: TokenStream::from(item),
283    })
284    .unwrap_or_compile_error()
285}
286
287#[doc = "Trace the execution of a function at the debug level."]
288#[doc = ""]
289#[doc = include_str!("./doc_span.md")]
290#[proc_macro_attribute]
291pub fn debug_span(
292    args: proc_macro::TokenStream,
293    item: proc_macro::TokenStream,
294) -> proc_macro::TokenStream {
295    span::expand_tokens(span::ExpandTokens {
296        level: Some(quote!(emit::Level::Debug)),
297        input: TokenStream::from(args),
298        item: TokenStream::from(item),
299    })
300    .unwrap_or_compile_error()
301}
302
303#[doc = "Trace the execution of a function at the info level."]
304#[doc = ""]
305#[doc = include_str!("./doc_span.md")]
306#[proc_macro_attribute]
307pub fn info_span(
308    args: proc_macro::TokenStream,
309    item: proc_macro::TokenStream,
310) -> proc_macro::TokenStream {
311    span::expand_tokens(span::ExpandTokens {
312        level: Some(quote!(emit::Level::Info)),
313        input: TokenStream::from(args),
314        item: TokenStream::from(item),
315    })
316    .unwrap_or_compile_error()
317}
318
319#[doc = "Trace the execution of a function at the warn level."]
320#[doc = ""]
321#[doc = include_str!("./doc_span.md")]
322#[proc_macro_attribute]
323pub fn warn_span(
324    args: proc_macro::TokenStream,
325    item: proc_macro::TokenStream,
326) -> proc_macro::TokenStream {
327    span::expand_tokens(span::ExpandTokens {
328        level: Some(quote!(emit::Level::Warn)),
329        input: TokenStream::from(args),
330        item: TokenStream::from(item),
331    })
332    .unwrap_or_compile_error()
333}
334
335#[doc = "Trace the execution of a function at the error level."]
336#[doc = ""]
337#[doc = include_str!("./doc_span.md")]
338#[proc_macro_attribute]
339pub fn error_span(
340    args: proc_macro::TokenStream,
341    item: proc_macro::TokenStream,
342) -> proc_macro::TokenStream {
343    span::expand_tokens(span::ExpandTokens {
344        level: Some(quote!(emit::Level::Error)),
345        input: TokenStream::from(args),
346        item: TokenStream::from(item),
347    })
348    .unwrap_or_compile_error()
349}
350
351#[doc = "Create a span that can be started and completed manually."]
352#[doc = ""]
353#[doc = include_str!("./doc_new_span.md")]
354#[proc_macro]
355pub fn new_span(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
356    span::expand_new_tokens(span::ExpandNewTokens {
357        level: None,
358        input: TokenStream::from(item),
359    })
360    .unwrap_or_compile_error()
361}
362
363#[doc = "Create a span at the debug level that can be started and completed manually."]
364#[doc = ""]
365#[doc = include_str!("./doc_new_span.md")]
366#[proc_macro]
367pub fn new_debug_span(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
368    span::expand_new_tokens(span::ExpandNewTokens {
369        level: Some(quote!(emit::Level::Debug)),
370        input: TokenStream::from(item),
371    })
372    .unwrap_or_compile_error()
373}
374
375#[doc = "Create a span at the info level that can be started and completed manually."]
376#[doc = ""]
377#[doc = include_str!("./doc_new_span.md")]
378#[proc_macro]
379pub fn new_info_span(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
380    span::expand_new_tokens(span::ExpandNewTokens {
381        level: Some(quote!(emit::Level::Info)),
382        input: TokenStream::from(item),
383    })
384    .unwrap_or_compile_error()
385}
386
387#[doc = "Create a span at the warn level that can be started and completed manually."]
388#[doc = ""]
389#[doc = include_str!("./doc_new_span.md")]
390#[proc_macro]
391pub fn new_warn_span(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
392    span::expand_new_tokens(span::ExpandNewTokens {
393        level: Some(quote!(emit::Level::Warn)),
394        input: TokenStream::from(item),
395    })
396    .unwrap_or_compile_error()
397}
398
399#[doc = "Create a span at the error level that can be started and completed manually."]
400#[doc = ""]
401#[doc = include_str!("./doc_new_span.md")]
402#[proc_macro]
403pub fn new_error_span(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
404    span::expand_new_tokens(span::ExpandNewTokens {
405        level: Some(quote!(emit::Level::Error)),
406        input: TokenStream::from(item),
407    })
408    .unwrap_or_compile_error()
409}
410
411#[doc = "Construct a template."]
412#[doc = ""]
413#[doc = include_str!("./doc_tpl.md")]
414#[proc_macro]
415pub fn tpl(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
416    build::expand_tpl_tokens(build::ExpandTplTokens {
417        input: TokenStream::from(item),
418    })
419    .unwrap_or_compile_error()
420}
421
422#[doc = "Emit an event."]
423#[doc = ""]
424#[doc = include_str!("./doc_emit.md")]
425#[proc_macro]
426pub fn emit(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
427    emit::expand_tokens(emit::ExpandTokens {
428        level: None,
429        input: TokenStream::from(item),
430    })
431    .unwrap_or_compile_error()
432}
433
434#[doc = "Emit an event at the debug level."]
435#[doc = ""]
436#[doc = include_str!("./doc_emit.md")]
437#[proc_macro]
438pub fn debug(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
439    emit::expand_tokens(emit::ExpandTokens {
440        level: Some(quote!(emit::Level::Debug)),
441        input: TokenStream::from(item),
442    })
443    .unwrap_or_compile_error()
444}
445
446#[doc = "Emit an event at the info level."]
447#[doc = ""]
448#[doc = include_str!("./doc_emit.md")]
449#[proc_macro]
450pub fn info(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
451    emit::expand_tokens(emit::ExpandTokens {
452        level: Some(quote!(emit::Level::Info)),
453        input: TokenStream::from(item),
454    })
455    .unwrap_or_compile_error()
456}
457
458#[doc = "Emit an event at the warn level."]
459#[doc = ""]
460#[doc = include_str!("./doc_emit.md")]
461#[proc_macro]
462pub fn warn(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
463    emit::expand_tokens(emit::ExpandTokens {
464        level: Some(quote!(emit::Level::Warn)),
465        input: TokenStream::from(item),
466    })
467    .unwrap_or_compile_error()
468}
469
470#[doc = "Emit an event at the error level."]
471#[doc = ""]
472#[doc = include_str!("./doc_emit.md")]
473#[proc_macro]
474pub fn error(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
475    emit::expand_tokens(emit::ExpandTokens {
476        level: Some(quote!(emit::Level::Error)),
477        input: TokenStream::from(item),
478    })
479    .unwrap_or_compile_error()
480}
481
482#[doc = "Emit a temporary event as a quick-and-dirty debugging aid."]
483#[doc = ""]
484#[doc = include_str!("./doc_dbg.md")]
485#[proc_macro]
486pub fn dbg(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
487    dbg::expand_tokens(dbg::ExpandTokens {
488        input: TokenStream::from(item),
489    })
490    .unwrap_or_compile_error()
491}
492
493/**
494Emit a metric sample.
495
496# Examples
497
498Emit a metric sample from a value:
499
500```ignore
501let my_metric = 42;
502
503emit::sample!(value: my_metric);
504```
505
506In the above example, the `name` is inferred to be `"my_metric"` using the name of the identifier in the `value` control parameter.
507
508The `name` can also be specified manually, and is required if `value` is not an identifier:
509
510```ignore
511emit::sample!(name: "my_metric", value: 42);
512```
513
514Properties can be attached to metric samples:
515
516```ignore
517let my_metric = 42;
518
519let metric = emit::sample!(value: my_metric, props: emit::props! { my_property: "some value" });
520```
521*/
522#[doc = ""]
523#[doc = include_str!("./doc_sample.md")]
524#[proc_macro]
525pub fn sample(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
526    sample::expand_tokens(sample::ExpandTokens {
527        agg: None,
528        input: TokenStream::from(item),
529    })
530    .unwrap_or_compile_error()
531}
532
533/**
534Emit a metric sample with `count` as its aggregation.
535
536# Examples
537
538See [`macro@sample`].
539*/
540#[doc = ""]
541#[doc = include_str!("./doc_sample.md")]
542#[proc_macro]
543pub fn count_sample(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
544    sample::expand_tokens(sample::ExpandTokens {
545        agg: Some({
546            let agg = emit_core::well_known::METRIC_AGG_COUNT;
547
548            quote!(#agg)
549        }),
550        input: TokenStream::from(item),
551    })
552    .unwrap_or_compile_error()
553}
554
555/**
556Emit a metric sample with `sum` as its aggregation.
557
558# Examples
559
560See [`macro@sample`].
561*/
562#[doc = ""]
563#[doc = include_str!("./doc_sample.md")]
564#[proc_macro]
565pub fn sum_sample(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
566    sample::expand_tokens(sample::ExpandTokens {
567        agg: Some({
568            let agg = emit_core::well_known::METRIC_AGG_SUM;
569
570            quote!(#agg)
571        }),
572        input: TokenStream::from(item),
573    })
574    .unwrap_or_compile_error()
575}
576
577/**
578Emit a metric sample with `min` as its aggregation.
579
580# Examples
581
582See [`macro@sample`].
583*/
584#[doc = ""]
585#[doc = include_str!("./doc_sample.md")]
586#[proc_macro]
587pub fn min_sample(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
588    sample::expand_tokens(sample::ExpandTokens {
589        agg: Some({
590            let agg = emit_core::well_known::METRIC_AGG_MIN;
591
592            quote!(#agg)
593        }),
594        input: TokenStream::from(item),
595    })
596    .unwrap_or_compile_error()
597}
598
599/**
600Emit a metric sample with `max` as its aggregation.
601
602# Examples
603
604See [`macro@sample`].
605*/
606#[doc = ""]
607#[doc = include_str!("./doc_sample.md")]
608#[proc_macro]
609pub fn max_sample(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
610    sample::expand_tokens(sample::ExpandTokens {
611        agg: Some({
612            let agg = emit_core::well_known::METRIC_AGG_MAX;
613
614            quote!(#agg)
615        }),
616        input: TokenStream::from(item),
617    })
618    .unwrap_or_compile_error()
619}
620
621/**
622Emit a metric sample with `last` as its aggregation.
623
624# Examples
625
626See [`macro@sample`].
627*/
628#[doc = ""]
629#[doc = include_str!("./doc_sample.md")]
630#[proc_macro]
631pub fn last_sample(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
632    sample::expand_tokens(sample::ExpandTokens {
633        agg: Some({
634            let agg = emit_core::well_known::METRIC_AGG_LAST;
635
636            quote!(#agg)
637        }),
638        input: TokenStream::from(item),
639    })
640    .unwrap_or_compile_error()
641}
642
643/**
644Construct a metric sample.
645
646# Examples
647
648Construct a metric sample from a value:
649
650```ignore
651let my_metric = 42;
652
653let metric = emit::metric!(value: my_metric);
654```
655
656In the above example, the `name` is inferred to be `"my_metric"` using the name of the identifier in the `value` control parameter.
657
658The `name` can also be specified manually, and is required if `value` is not an identifier:
659
660```ignore
661let metric = emit::metric!(name: "my_metric", value: 42);
662```
663
664Properties can be attached to metric samples:
665
666```ignore
667let my_metric = 42;
668
669let metric = emit::metric!(value: my_metric, props: emit::props! { my_property: "some value" });
670```
671*/
672#[doc = ""]
673#[doc = include_str!("./doc_metric.md")]
674#[proc_macro]
675pub fn metric(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
676    sample::expand_metric_tokens(sample::ExpandTokens {
677        agg: None,
678        input: TokenStream::from(item),
679    })
680    .unwrap_or_compile_error()
681}
682
683/**
684Construct a metric sample with `count` as its aggregation.
685
686# Examples
687
688See [`macro@metric`].
689*/
690#[doc = ""]
691#[doc = include_str!("./doc_metric.md")]
692#[proc_macro]
693pub fn count_metric(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
694    sample::expand_metric_tokens(sample::ExpandTokens {
695        agg: Some({
696            let agg = emit_core::well_known::METRIC_AGG_COUNT;
697
698            quote!(#agg)
699        }),
700        input: TokenStream::from(item),
701    })
702    .unwrap_or_compile_error()
703}
704
705/**
706Construct a metric sample with `sum` as its aggregation.
707
708# Examples
709
710See [`macro@metric`].
711*/
712#[doc = ""]
713#[doc = include_str!("./doc_metric.md")]
714#[proc_macro]
715pub fn sum_metric(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
716    sample::expand_metric_tokens(sample::ExpandTokens {
717        agg: Some({
718            let agg = emit_core::well_known::METRIC_AGG_SUM;
719
720            quote!(#agg)
721        }),
722        input: TokenStream::from(item),
723    })
724    .unwrap_or_compile_error()
725}
726
727/**
728Construct a metric sample with `min` as its aggregation.
729
730# Examples
731
732See [`macro@metric`].
733*/
734#[doc = ""]
735#[doc = include_str!("./doc_metric.md")]
736#[proc_macro]
737pub fn min_metric(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
738    sample::expand_metric_tokens(sample::ExpandTokens {
739        agg: Some({
740            let agg = emit_core::well_known::METRIC_AGG_MIN;
741
742            quote!(#agg)
743        }),
744        input: TokenStream::from(item),
745    })
746    .unwrap_or_compile_error()
747}
748
749/**
750Construct a metric sample with `max` as its aggregation.
751
752# Examples
753
754See [`macro@metric`].
755*/
756#[doc = ""]
757#[doc = include_str!("./doc_metric.md")]
758#[proc_macro]
759pub fn max_metric(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
760    sample::expand_metric_tokens(sample::ExpandTokens {
761        agg: Some({
762            let agg = emit_core::well_known::METRIC_AGG_MAX;
763
764            quote!(#agg)
765        }),
766        input: TokenStream::from(item),
767    })
768    .unwrap_or_compile_error()
769}
770
771/**
772Construct a metric sample with `last` as its aggregation.
773
774# Examples
775
776See [`macro@metric`].
777*/
778#[doc = ""]
779#[doc = include_str!("./doc_metric.md")]
780#[proc_macro]
781pub fn last_metric(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
782    sample::expand_metric_tokens(sample::ExpandTokens {
783        agg: Some({
784            let agg = emit_core::well_known::METRIC_AGG_LAST;
785
786            quote!(#agg)
787        }),
788        input: TokenStream::from(item),
789    })
790    .unwrap_or_compile_error()
791}
792
793/**
794Construct a path.
795
796# Syntax
797
798```text
799path
800```
801
802where
803
804- `path`: A string literal containing a valid `emit` path.
805
806# Returns
807
808An `emit::Path`.
809*/
810#[proc_macro]
811pub fn path(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
812    build::expand_path_tokens(build::ExpandPathTokens {
813        input: TokenStream::from(item),
814    })
815    .unwrap_or_compile_error()
816}
817
818/**
819Construct a set of properties.
820
821# Syntax
822
823```text
824(property),*
825```
826
827where
828
829- `property`: A Rust field-value for a property. The identifier of the field-value is the key of the property.
830
831# Returns
832
833An `impl emit::Props`.
834*/
835#[proc_macro]
836pub fn props(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
837    build::expand_props_tokens(build::ExpandPropsTokens {
838        input: TokenStream::from(item),
839    })
840    .unwrap_or_compile_error()
841}
842
843/**
844Specify Rust format flags to use when rendering a property in a template.
845
846# Syntax
847
848```text
849fmt_string
850```
851
852where
853
854- `fmt_string`: A string literal with the format flags, like `":?"`. See the [`std::fmt`](https://doc.rust-lang.org/std/fmt/index.html) docs for details on available flags.
855
856# Applicable to
857
858This attribute can be applied to properties that appear in a template.
859*/
860#[proc_macro_attribute]
861pub fn fmt(
862    args: proc_macro::TokenStream,
863    item: proc_macro::TokenStream,
864) -> proc_macro::TokenStream {
865    (hook::get("fmt").unwrap())(TokenStream::from(args), TokenStream::from(item))
866        .unwrap_or_compile_error()
867}
868
869/**
870Specify the key for a property.
871
872# Syntax
873
874```text
875key
876```
877
878where
879
880- `key`: A string literal with the key to use. The key doesn't need to be a valid Rust identifier.
881
882This macro can also be called with an explicit `name` identifier:
883
884```text
885name: key
886```
887
888where
889
890- `key`: An expression that evaluates to a string value for the key to use. The key doesn't need to be a valid Rust identifier.
891
892# Applicable to
893
894This attribute can be applied to properties.
895*/
896#[proc_macro_attribute]
897pub fn key(
898    args: proc_macro::TokenStream,
899    item: proc_macro::TokenStream,
900) -> proc_macro::TokenStream {
901    (hook::get("key").unwrap())(TokenStream::from(args), TokenStream::from(item))
902        .unwrap_or_compile_error()
903}
904
905/**
906Specify that a property value of `None` should not be captured, instead of being captured as `null`.
907
908# Syntax
909
910This macro doesn't accept any arguments.
911
912# Applicable to
913
914This attribute can be applied to properties where the type is `Option<&T>`.
915*/
916#[proc_macro_attribute]
917pub fn optional(
918    args: proc_macro::TokenStream,
919    item: proc_macro::TokenStream,
920) -> proc_macro::TokenStream {
921    (hook::get("optional").unwrap())(TokenStream::from(args), TokenStream::from(item))
922        .unwrap_or_compile_error()
923}
924
925/**
926Capture a property using its `ToValue` implementation.
927
928# Syntax
929
930This macro doesn't accept any arguments.
931
932# Applicable to
933
934This attribute can be applied to properties.
935*/
936#[proc_macro_attribute]
937pub fn as_value(
938    args: proc_macro::TokenStream,
939    item: proc_macro::TokenStream,
940) -> proc_macro::TokenStream {
941    (hook::get("as_value").unwrap())(TokenStream::from(args), TokenStream::from(item))
942        .unwrap_or_compile_error()
943}
944
945/**
946Capture a property using its `Debug` implementation.
947
948# Syntax
949
950This macro doesn't accept any arguments.
951
952# Applicable to
953
954This attribute can be applied to properties.
955*/
956#[proc_macro_attribute]
957pub fn as_debug(
958    args: proc_macro::TokenStream,
959    item: proc_macro::TokenStream,
960) -> proc_macro::TokenStream {
961    (hook::get("as_debug").unwrap())(TokenStream::from(args), TokenStream::from(item))
962        .unwrap_or_compile_error()
963}
964
965/**
966Capture a property using its `Display` implementation.
967
968# Syntax
969
970This macro doesn't accept any arguments.
971
972# Applicable to
973
974This attribute can be applied to properties.
975*/
976#[proc_macro_attribute]
977pub fn as_display(
978    args: proc_macro::TokenStream,
979    item: proc_macro::TokenStream,
980) -> proc_macro::TokenStream {
981    (hook::get("as_display").unwrap())(TokenStream::from(args), TokenStream::from(item))
982        .unwrap_or_compile_error()
983}
984
985/**
986Capture a property using its `sval::Value` implementation.
987
988# Syntax
989
990This macro doesn't accept any arguments.
991
992# Applicable to
993
994This attribute can be applied to properties.
995*/
996#[proc_macro_attribute]
997pub fn as_sval(
998    args: proc_macro::TokenStream,
999    item: proc_macro::TokenStream,
1000) -> proc_macro::TokenStream {
1001    (hook::get("as_sval").unwrap())(TokenStream::from(args), TokenStream::from(item))
1002        .unwrap_or_compile_error()
1003}
1004
1005/**
1006Capture a property using its `serde::Serialize` implementation.
1007
1008# Syntax
1009
1010This macro doesn't accept any arguments.
1011
1012# Applicable to
1013
1014This attribute can be applied to properties.
1015*/
1016#[proc_macro_attribute]
1017pub fn as_serde(
1018    args: proc_macro::TokenStream,
1019    item: proc_macro::TokenStream,
1020) -> proc_macro::TokenStream {
1021    (hook::get("as_serde").unwrap())(TokenStream::from(args), TokenStream::from(item))
1022        .unwrap_or_compile_error()
1023}
1024
1025/**
1026Capture a property using its `Error` implementation.
1027
1028# Syntax
1029
1030This macro doesn't accept any arguments.
1031
1032# Applicable to
1033
1034This attribute can be applied to properties.
1035*/
1036#[proc_macro_attribute]
1037pub fn as_error(
1038    args: proc_macro::TokenStream,
1039    item: proc_macro::TokenStream,
1040) -> proc_macro::TokenStream {
1041    (hook::get("as_error").unwrap())(TokenStream::from(args), TokenStream::from(item))
1042        .unwrap_or_compile_error()
1043}
1044
1045fn capture_as(
1046    name: &'static str,
1047    args: TokenStream,
1048    expr: TokenStream,
1049    as_fn: TokenStream,
1050    as_anon_fn: TokenStream,
1051) -> syn::Result<TokenStream> {
1052    capture::rename_hook_tokens(capture::RenameHookTokens {
1053        name,
1054        args,
1055        expr,
1056        to: |args: &capture::Args| {
1057            if args.inspect {
1058                as_fn.clone()
1059            } else {
1060                as_anon_fn.clone()
1061            }
1062        },
1063    })
1064}