Skip to main content

facet_macros/
lib.rs

1//! [![Coverage Status](https://coveralls.io/repos/github/facet-rs/facet-macros/badge.svg?branch=main)](https://coveralls.io/github/facet-rs/facet?branch=main)
2//! [![crates.io](https://img.shields.io/crates/v/facet-macros.svg)](https://crates.io/crates/facet-macros)
3//! [![documentation](https://docs.rs/facet-macros/badge.svg)](https://docs.rs/facet-macros)
4//! [![MIT/Apache-2.0 licensed](https://img.shields.io/crates/l/facet-macros.svg)](./LICENSE)
5//! [![Discord](https://img.shields.io/discord/1379550208551026748?logo=discord&label=discord)](https://discord.gg/JhD7CwCJ8F)
6//!
7//! Implements the `Facet` derive macro for facet. Uses [unsynn](https://crates.io/crates/unsynn) to provide fast compilation times.
8//!
9#![doc = include_str!("../readme-footer.md")]
10
11#[proc_macro_derive(Facet, attributes(facet))]
12pub fn facet_macros(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
13    facet_macros_impl::facet_macros(input.into()).into()
14}
15
16/// Internal proc macro for extension attribute resolution.
17///
18/// This is called by the `Facet` derive macro to forward extension attributes
19/// to their respective crate's dispatcher macro while preserving spans for
20/// better error messages.
21#[doc(hidden)]
22#[proc_macro]
23pub fn __ext(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
24    facet_macros_impl::ext_attr(input.into()).into()
25}
26
27// ============================================================================
28// ATTRIBUTE GRAMMAR PROC-MACROS
29// ============================================================================
30
31/// Internal proc macro for compiling attribute grammars.
32///
33/// This is called by `define_attr_grammar!` to generate type definitions
34/// and dispatcher macros from a grammar DSL.
35#[doc(hidden)]
36#[proc_macro]
37pub fn __make_parse_attr(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
38    facet_macros_impl::attr_grammar::make_parse_attr(input.into()).into()
39}
40
41/// Internal proc macro for unified attribute dispatch.
42///
43/// Routes parsed attribute names to the appropriate variant handlers
44/// (unit, newtype, or struct).
45#[doc(hidden)]
46#[proc_macro]
47pub fn __dispatch_attr(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
48    facet_macros_impl::attr_grammar::dispatch_attr(input.into()).into()
49}
50
51/// Internal proc macro for building struct field values.
52///
53/// Parses struct field assignments with type validation and helpful
54/// error messages.
55#[doc(hidden)]
56#[proc_macro]
57pub fn __build_struct_fields(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
58    facet_macros_impl::attr_grammar::build_struct_fields(input.into()).into()
59}
60
61/// Internal proc macro for attribute error messages.
62///
63/// Generates compile_error! with typo suggestions for unknown attributes.
64#[doc(hidden)]
65#[proc_macro]
66pub fn __attr_error(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
67    facet_macros_impl::attr_grammar::attr_error(input.into()).into()
68}
69
70/// Internal proc macro for field error messages.
71///
72/// Generates compile_error! with typo suggestions for unknown fields.
73#[doc(hidden)]
74#[proc_macro]
75pub fn __field_error(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
76    facet_macros_impl::attr_grammar::field_error(input.into()).into()
77}
78
79/// Internal proc macro for spanned error messages.
80///
81/// A generic helper for emitting errors with precise spans.
82#[doc(hidden)]
83#[proc_macro]
84pub fn __spanned_error(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
85    facet_macros_impl::attr_grammar::spanned_error(input.into()).into()
86}
87
88#[cfg(feature = "function")]
89#[proc_macro_attribute]
90pub fn facet_fn(
91    attr: proc_macro::TokenStream,
92    item: proc_macro::TokenStream,
93) -> proc_macro::TokenStream {
94    facet_macros_impl::function::facet_fn(attr.into(), item.into()).into()
95}
96
97#[cfg(feature = "function")]
98#[proc_macro]
99pub fn fn_shape(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
100    facet_macros_impl::function::fn_shape(input.into()).into()
101}
102
103/// Internal proc macro for unknown extension attribute errors.
104///
105/// This generates a compile_error! with the span pointing to the unknown identifier.
106#[doc(hidden)]
107#[proc_macro]
108pub fn __unknown_attr(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
109    facet_macros_impl::unknown_attr(input.into()).into()
110}
111
112// ============================================================================
113// PLUGIN SYSTEM PROC-MACROS
114// ============================================================================
115
116/// Internal proc macro for plugin chain finalization.
117///
118/// This is called at the end of a plugin chain to:
119/// 1. Parse the type definition ONCE
120/// 2. Generate the base Facet impl
121/// 3. Call each registered plugin's code generator
122///
123/// Input format:
124/// ```ignore
125/// __facet_finalize! {
126///     @tokens { struct Foo { ... } }
127///     @plugins { "Error", }
128///     @facet_crate { ::facet }
129/// }
130/// ```
131#[doc(hidden)]
132#[proc_macro]
133pub fn __facet_finalize(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
134    facet_macros_impl::facet_finalize(input.into()).into()
135}
136
137/// Internal proc macro for "does not accept arguments" errors.
138///
139/// Input: `"ns::attr", token`
140/// Generates compile_error! with span on the token.
141#[doc(hidden)]
142#[proc_macro]
143pub fn __no_args(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
144    facet_macros_impl::no_args(input.into()).into()
145}
146
147/// Attribute macro that runs cleanup code when a method returns an error.
148///
149/// # Usage
150///
151/// ```ignore
152/// #[on_error(self.cleanup())]
153/// pub fn do_something(&mut self) -> Result<(), Error> {
154///     self.inner_work()?;
155///     Ok(())
156/// }
157/// ```
158///
159/// For methods returning `Result<&mut Self, E>`, the macro properly handles
160/// the borrow by discarding the returned reference and returning a fresh `Ok(self)`:
161///
162/// ```ignore
163/// #[on_error(self.poison_and_cleanup())]
164/// pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
165///     self.require_active()?;
166///     // ... implementation
167///     Ok(self)
168/// }
169/// ```
170#[proc_macro_attribute]
171pub fn on_error(
172    attr: proc_macro::TokenStream,
173    item: proc_macro::TokenStream,
174) -> proc_macro::TokenStream {
175    facet_macros_impl::on_error(attr.into(), item.into()).into()
176}