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/// Generate setters for the given options struct.
34/// Arguments:
35///   * the fully-qualified path of the struct type
36#[import_tokens_attr]
37#[with_custom_parsing(crate::option::OptionSettersArgs)]
38#[proc_macro_attribute]
39pub fn option_setters(
40    attr: proc_macro::TokenStream,
41    item: proc_macro::TokenStream,
42) -> proc_macro::TokenStream {
43    crate::option::option_setters(attr, item, __custom_tokens)
44}
45
46/// Export the setters in this `impl` block so they can be used in `options_doc`.
47/// Arguments:
48///   * an identifier for the exported list
49///   * an optional `extra = [fn_name[,..]]` list of additional setters to include
50#[proc_macro_attribute]
51pub fn export_doc(
52    attr: proc_macro::TokenStream,
53    item: proc_macro::TokenStream,
54) -> proc_macro::TokenStream {
55    crate::rustdoc::export_doc(attr, item)
56}
57
58/// Include options documentation generated by `export_doc` in the rustdoc for this method:
59/// Arguments:
60///   * the doc identifier given to `export_doc`
61///   * an optional `sync` keyword that alters the documentation to be appropriate for a sync action
62#[import_tokens_attr]
63#[with_custom_parsing(crate::rustdoc::OptionsDocArgs)]
64#[proc_macro_attribute]
65pub fn options_doc(
66    attr: proc_macro::TokenStream,
67    item: proc_macro::TokenStream,
68) -> proc_macro::TokenStream {
69    crate::rustdoc::options_doc(attr, item, __custom_tokens)
70}
71
72/// Parse an identifier with a specific expected value.
73fn parse_name(input: ParseStream, name: &str) -> syn::Result<Ident> {
74    let ident = input.parse::<Ident>()?;
75    if ident != name {
76        return Err(Error::new(
77            ident.span(),
78            format!("expected '{}', got '{}'", name, ident),
79        ));
80    }
81    Ok(ident)
82}
83
84macro_rules! macro_error {
85    ($span:expr, $($message:tt)+) => {{
86        return Error::new($span, format!($($message)+)).into_compile_error().into();
87    }};
88}
89use macro_error;
90
91fn parse_ident_list(input: ParseStream, name: &str) -> syn::Result<Vec<Ident>> {
92    parse_name(input, name)?;
93    input.parse::<Token![=]>()?;
94    let content;
95    bracketed!(content in input);
96    let punc = Punctuated::<Ident, Token![,]>::parse_terminated(&content)?;
97    Ok(punc.into_pairs().map(|p| p.into_value()).collect())
98}