Skip to main content

reinhardt_graphql_macros/
lib.rs

1//! Derive macros for reinhardt-graphql
2//!
3//! This crate provides derive macros to simplify gRPC ↔ GraphQL integration
4//! and dependency injection support.
5
6use proc_macro::TokenStream;
7use syn::{DeriveInput, parse_macro_input};
8
9mod convert;
10mod crate_paths;
11mod graphql_handler;
12mod subscription;
13
14/// Generate automatic conversion between Protobuf and GraphQL types
15///
16/// This automatically generates:
17/// - `From<proto::User> for User`
18/// - `From<User> for proto::User`
19#[proc_macro_derive(GrpcGraphQLConvert, attributes(graphql, proto))]
20pub fn derive_grpc_graphql_convert(input: TokenStream) -> TokenStream {
21	let input = parse_macro_input!(input as DeriveInput);
22	convert::expand_derive(input)
23		.unwrap_or_else(|err| err.to_compile_error())
24		.into()
25}
26
27/// Automatically map gRPC Subscription to GraphQL Subscription
28///
29/// This automatically generates GraphQL Subscription implementation.
30/// Handles Rust 2024 lifetime issues.
31#[proc_macro_derive(GrpcSubscription, attributes(grpc, graphql))]
32pub fn derive_grpc_subscription(input: TokenStream) -> TokenStream {
33	let input = parse_macro_input!(input as DeriveInput);
34	subscription::expand_derive(input)
35		.unwrap_or_else(|err| err.to_compile_error())
36		.into()
37}
38
39/// Attribute macro for GraphQL resolvers with dependency injection support
40///
41/// This macro enables the use of `#[inject]` parameters in GraphQL resolver functions,
42/// allowing automatic dependency resolution from the `InjectionContext`.
43///
44/// # Parameters
45///
46/// Regular parameters are passed through as-is. Parameters marked with `#[inject]`
47/// are automatically resolved from the DI context.
48///
49/// # Requirements
50///
51/// 1. The function must have an `async_graphql::Context<'_>` parameter
52/// 2. The schema must have an `InjectionContext` in its data (use `.data(injection_ctx)`)
53/// 3. All injected types must implement `Injectable`
54/// 4. The function must be `async`
55///
56/// # Error Handling
57///
58/// If dependency injection fails, the function returns `async_graphql::Error`
59/// with an error message describing the failure.
60#[proc_macro_attribute]
61pub fn graphql_handler(_attr: TokenStream, item: TokenStream) -> TokenStream {
62	let input = parse_macro_input!(item as syn::ItemFn);
63
64	graphql_handler::expand_graphql_handler(input)
65		.unwrap_or_else(|err| err.to_compile_error())
66		.into()
67}