mz_ore_proc/
lib.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License in the LICENSE file at the
6// root of this repository, or online at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Internal utility proc-macros for Materialize.
17//!
18//! Note: This is separate from the `mz_ore` crate because `proc-macro` crates are only allowed
19//! to export procedural macros and nothing else.
20
21use proc_macro::TokenStream;
22
23mod instrument;
24mod static_list;
25mod test;
26
27/// A macro that collects all of the static objects of a specific type in the annotated module into
28/// a single list.
29///
30/// ```
31/// use mz_ore_proc::static_list;
32///
33/// #[static_list(ty = "usize", name = "ALL_NUMS", expected_count = 3)]
34/// pub mod my_items {
35///     pub static FOO: usize = 1;
36///
37///     // Won't get included in the list, because it's not a usize.
38///     pub static NON_USIZE: u8 = 10;
39///
40///     // Nested modules also work.
41///     pub mod inner {
42///         pub static BAR: usize = 5;
43///         pub static BAZ: usize = 11;
44///     }
45/// }
46///
47/// assert_eq!(ALL_NUMS, &[&1usize, &5, &11]);
48/// ```
49///
50/// ### Wrong expected count.
51///
52/// You're required to specify an expected count of items as a smoke test to make sure all of the
53/// items you think should get included, are included.
54///
55/// ```compile_fail
56/// # use mz_ore_proc::static_list;
57/// #[static_list(ty = "usize", name = "ALL_NUMS", expected_count = 2)]
58/// pub mod items {
59///     pub static A: usize = 10;
60///     pub static B: isize = 20;
61/// }
62/// ```
63#[proc_macro_attribute]
64pub fn static_list(args: TokenStream, item: TokenStream) -> TokenStream {
65    static_list::static_list_impl(args, item)
66}
67
68/// Materialize wrapper around the `#[tracing::insrument]` macro.
69///
70/// We wrap the `tracing::instrument` macro to skip tracing all arguments by default, this prevents
71/// noisy or actively harmful things (e.g. the entire Catalog) from accidentally getting traced. If
72/// you would like to include a function's argument in the traced span, you can use the
73/// `fields(...)` syntax.
74#[proc_macro_attribute]
75pub fn instrument(attr: TokenStream, item: TokenStream) -> TokenStream {
76    instrument::instrument_impl(attr, item)
77}
78
79/// Materialize wrapper around the `test` macro.
80///
81/// The wrapper automatically initializes our logging infrastructure.
82#[proc_macro_attribute]
83pub fn test(attr: TokenStream, item: TokenStream) -> TokenStream {
84    test::test_impl(attr, item)
85}