Skip to main content

monty_macros/
lib.rs

1//! Procedural macros for the `monty` Python interpreter.
2//!
3//! - `#[derive(FromArgs)]` — `ArgValues` → typed struct (positional/kwarg
4//!   dispatch, defaults, type coercion via `FromValue`, refcount cleanup).
5//! - `#[derive(ToArgs)]` — typed struct → host call arguments.
6//!
7//! Generated code is internal to `monty` (`FromArgs`) and `monty-types` (`ToArgs`).
8//! See the crate `README.md` for usage and the docstrings on `StructAttrs` /
9//! `FieldKind` in `from_args.rs` for the full attribute surface.
10
11use proc_macro::TokenStream;
12
13mod from_args;
14mod to_args;
15
16/// Derive `FromArgs::from_args`. Each struct field becomes a Python
17/// parameter; the generated body parses an `ArgValues` and populates the
18/// struct, returning `RunResult<Self>`.
19///
20/// Field types must implement `monty::args::FromValue`. Fields must appear
21/// in Python signature order:
22/// `[pos_only…] [pos_or_keyword…] [varargs] [kw_only…] [varkwargs]`, with
23/// required fields preceding optional ones in each region.
24///
25/// `#[from_args(name = "...")]` is required on the struct. The remaining
26/// attributes select CPython error-wording style or field roles; see the
27/// crate `README.md` and the source docstrings.
28#[proc_macro_derive(FromArgs, attributes(from_args))]
29pub fn derive_from_args(input: TokenStream) -> TokenStream {
30    let input = syn::parse_macro_input!(input as syn::DeriveInput);
31    from_args::expand(&input)
32        .unwrap_or_else(syn::Error::into_compile_error)
33        .into()
34}
35
36/// Projects a struct into host call arguments using `#[from_args(...)]` attributes.
37/// `varargs` fields contribute one positional argument per element.
38#[proc_macro_derive(ToArgs, attributes(from_args))]
39pub fn derive_to_args(input: TokenStream) -> TokenStream {
40    let input = syn::parse_macro_input!(input as syn::DeriveInput);
41    to_args::expand(&input)
42        .unwrap_or_else(syn::Error::into_compile_error)
43        .into()
44}