Skip to main content

graphrecords_macros/
lib.rs

1mod attribute;
2mod query;
3
4use proc_macro::TokenStream;
5use proc_macro_crate::{FoundCrate, crate_name};
6use proc_macro2::Span;
7use syn::{DeriveInput, Error, Path, Result, parse_macro_input, parse_str};
8
9#[proc_macro_derive(PlanNode, attributes(plan, input, argument))]
10pub fn derive_plan_node(input: TokenStream) -> TokenStream {
11    let input = parse_macro_input!(input as DeriveInput);
12
13    query::optimizer::plan::node::expand(&input)
14        .unwrap_or_else(Error::into_compile_error)
15        .into()
16}
17
18#[proc_macro_derive(MatchInputs, attributes(plan, input, argument))]
19pub fn derive_match_inputs(input: TokenStream) -> TokenStream {
20    let input = parse_macro_input!(input as DeriveInput);
21
22    query::optimizer::plan::match_inputs::expand(&input)
23        .unwrap_or_else(Error::into_compile_error)
24        .into()
25}
26
27#[proc_macro_derive(PlanIdentity, attributes(plan, input, argument))]
28pub fn derive_plan_identity(input: TokenStream) -> TokenStream {
29    let input = parse_macro_input!(input as DeriveInput);
30
31    query::optimizer::plan::plan_identity::expand(&input)
32        .unwrap_or_else(Error::into_compile_error)
33        .into()
34}
35
36#[proc_macro_derive(PlanInputs, attributes(plan, input, argument))]
37pub fn derive_plan_inputs(input: TokenStream) -> TokenStream {
38    let input = parse_macro_input!(input as DeriveInput);
39
40    query::optimizer::plan::plan_inputs::expand(&input)
41        .unwrap_or_else(Error::into_compile_error)
42        .into()
43}
44
45#[proc_macro_derive(OperationInputs, attributes(plan, input, argument))]
46pub fn derive_operation_inputs(input: TokenStream) -> TokenStream {
47    let input = parse_macro_input!(input as DeriveInput);
48
49    query::optimizer::plan::operation_inputs::expand(&input)
50        .unwrap_or_else(Error::into_compile_error)
51        .into()
52}
53
54#[proc_macro_derive(OptimizePlan, attributes(plan, input, argument))]
55pub fn derive_optimize_plan(input: TokenStream) -> TokenStream {
56    let input = parse_macro_input!(input as DeriveInput);
57
58    query::optimizer::plan::optimize_inputs::expand(&input)
59        .unwrap_or_else(Error::into_compile_error)
60        .into()
61}
62
63#[proc_macro_derive(Explain, attributes(explain, input, argument))]
64pub fn derive_explain(input: TokenStream) -> TokenStream {
65    let input = parse_macro_input!(input as DeriveInput);
66
67    query::explain::expand(&input)
68        .unwrap_or_else(Error::into_compile_error)
69        .into()
70}
71
72#[proc_macro_derive(OptimizerHints, attributes(plan, input, argument))]
73pub fn derive_optimizer_hints(input: TokenStream) -> TokenStream {
74    let input = parse_macro_input!(input as DeriveInput);
75
76    query::optimizer::plan::optimizer_hints::expand(&input)
77        .unwrap_or_else(Error::into_compile_error)
78        .into()
79}
80
81#[proc_macro_derive(Operation, attributes(operation, plan, input, argument))]
82pub fn derive_operation(input: TokenStream) -> TokenStream {
83    let input = parse_macro_input!(input as DeriveInput);
84
85    query::operation::expand(&input)
86        .unwrap_or_else(Error::into_compile_error)
87        .into()
88}
89
90#[proc_macro_derive(PhaseLabel, attributes(phase_label))]
91pub fn derive_phase_label(input: TokenStream) -> TokenStream {
92    let input = parse_macro_input!(input as DeriveInput);
93
94    query::optimizer::phase_label::expand(&input)
95        .unwrap_or_else(Error::into_compile_error)
96        .into()
97}
98
99pub(crate) fn resolve_crate_path(package: &str, facade_module: &str) -> Result<Path> {
100    const FACADE: &str = "graphrecords";
101
102    match crate_name(package) {
103        Ok(FoundCrate::Itself) => parse_str("crate"),
104        Ok(FoundCrate::Name(name)) => parse_str(&format!("::{name}")),
105        Err(_) => match crate_name(FACADE) {
106            Ok(FoundCrate::Itself) => parse_str(&format!("crate::{facade_module}")),
107            Ok(FoundCrate::Name(name)) => parse_str(&format!("::{name}::{facade_module}")),
108            Err(error) => Err(Error::new(
109                Span::call_site(),
110                format!(
111                    "`{FACADE}` or `{package}` must be a dependency to derive this macro: {error}"
112                ),
113            )),
114        },
115    }
116}