mongodb_internal_macros/
lib.rs

1extern crate proc_macro;
2
3mod action_impl;
4mod option;
5mod rustdoc;
6
7use macro_magic::import_tokens_attr;
8use syn::{bracketed, parse::ParseStream, punctuated::Punctuated, Error, Ident, Token};
9
10/// Generates:
11/// * an `IntoFuture` executing the given method body
12/// * an opaque wrapper type for the future in case we want to do something more fancy than
13///   BoxFuture.
14/// * a `run` method for sync execution, optionally with a wrapper function
15#[proc_macro_attribute]
16pub fn action_impl(
17    attrs: proc_macro::TokenStream,
18    input: proc_macro::TokenStream,
19) -> proc_macro::TokenStream {
20    crate::action_impl::action_impl(attrs, input)
21}
22
23/// Enables rustdoc links to types that link individually to each type
24/// component.
25#[proc_macro_attribute]
26pub fn deeplink(
27    attr: proc_macro::TokenStream,
28    item: proc_macro::TokenStream,
29) -> proc_macro::TokenStream {
30    crate::rustdoc::deeplink(attr, item)
31}
32
33#[import_tokens_attr]
34#[with_custom_parsing(crate::option::OptionSettersArgs)]
35#[proc_macro_attribute]
36pub fn option_setters(
37    attr: proc_macro::TokenStream,
38    item: proc_macro::TokenStream,
39) -> proc_macro::TokenStream {
40    crate::option::option_setters(attr, item, __custom_tokens)
41}
42
43#[proc_macro_attribute]
44pub fn export_doc(
45    attr: proc_macro::TokenStream,
46    item: proc_macro::TokenStream,
47) -> proc_macro::TokenStream {
48    crate::rustdoc::export_doc(attr, item)
49}
50
51#[import_tokens_attr]
52#[with_custom_parsing(crate::rustdoc::OptionsDocArgs)]
53#[proc_macro_attribute]
54pub fn options_doc(
55    attr: proc_macro::TokenStream,
56    item: proc_macro::TokenStream,
57) -> proc_macro::TokenStream {
58    crate::rustdoc::options_doc(attr, item, __custom_tokens)
59}
60
61/// Parse an identifier with a specific expected value.
62fn parse_name(input: ParseStream, name: &str) -> syn::Result<Ident> {
63    let ident = input.parse::<Ident>()?;
64    if ident.to_string() != name {
65        return Err(Error::new(
66            ident.span(),
67            format!("expected '{}', got '{}'", name, ident),
68        ));
69    }
70    Ok(ident)
71}
72
73macro_rules! macro_error {
74    ($span:expr, $($message:tt)+) => {{
75        return Error::new($span, format!($($message)+)).into_compile_error().into();
76    }};
77}
78use macro_error;
79
80fn parse_ident_list(input: ParseStream, name: &str) -> syn::Result<Vec<Ident>> {
81    parse_name(input, name)?;
82    input.parse::<Token![=]>()?;
83    let content;
84    bracketed!(content in input);
85    let punc = Punctuated::<Ident, Token![,]>::parse_terminated(&content)?;
86    Ok(punc.into_pairs().map(|p| p.into_value()).collect())
87}