1use proc_macro::TokenStream;
2use pyro_macro::format::DocRec;
3use quote::quote;
4use syn::{ItemFn, ItemStruct, parse_macro_input, parse_quote, parse2};
5
6#[proc_macro_attribute]
7pub fn bridgeable(args: TokenStream, input: TokenStream) -> TokenStream {
8 let args = parse_macro_input!(args as pyro_macro::format::BridgeableArgs);
9 let mut item = parse_macro_input!(input as ItemStruct);
10
11 match pyro_macro::format::bridgeable::bridgeable(&args, &mut item, &parse_quote!(::pyroduct)) {
12 Ok(v) => v.into(),
13 Err(error) => error.to_compile_error().into(),
14 }
15}
16
17#[proc_macro_attribute]
18pub fn magma(args: TokenStream, input: TokenStream) -> TokenStream {
19 let args = parse_macro_input!(args as pyro_macro::format::BridgeableArgs);
20 let mut item = parse_macro_input!(input as ItemStruct);
21
22 match pyro_macro::format::magma(args, &mut item, &parse_quote!(::pyroduct)) {
23 Ok(v) => v.into(),
24 Err(error) => error.to_compile_error().into(),
25 }
26}
27
28#[proc_macro]
29pub fn library(input: TokenStream) -> TokenStream {
30 let args = parse_macro_input!(input as pyro_macro::format::library::LibraryArgs);
31
32 pyro_macro::format::library::create_ident(
33 syn::parse_quote!(::pyroduct),
34 &args.meta,
35 args.no_ffi,
36 )
37 .into()
38}
39
40#[proc_macro_derive(Document)]
41pub fn document(input: TokenStream) -> TokenStream {
42 let item = parse_macro_input!(input as ItemStruct);
43 match pyro_macro::format::documentation::generate_documented_impl(
44 &item,
45 &parse_quote!(::pyroduct),
46 DocRec::NoReq,
47 ) {
48 Ok(v) => v.into(),
49 Err(error) => error.to_compile_error().into(),
50 }
51}
52
53#[proc_macro_derive(DocumentRef)]
54pub fn document_ref(input: TokenStream) -> TokenStream {
55 let item = parse_macro_input!(input as ItemStruct);
56 match pyro_macro::format::documentation::ref_documentation(
57 &item,
58 &parse_quote!(::pyroduct),
59 DocRec::NoReq,
60 ) {
61 Ok(v) => v.into(),
62 Err(error) => error.to_compile_error().into(),
63 }
64}
65
66#[proc_macro_derive(DeepRef)]
67pub fn derive_deep_ref(input: TokenStream) -> TokenStream {
68 let item = parse_macro_input!(input as ItemStruct);
69 match pyro_macro::format::deep_ref::deep_ref(&item, &parse_quote!(::pyroduct), &vec![]) {
70 Ok(v) => v.into(),
71 Err(error) => error.to_compile_error().into(),
72 }
73}
74
75#[proc_macro_derive(DeepRefArchived)]
76pub fn derive_deep_ref_archived(input: TokenStream) -> TokenStream {
77 let item = parse_macro_input!(input as ItemStruct);
78 match pyro_macro::format::deep_ref::deep_ref_rkyv(&item, &parse_quote!(::pyroduct)) {
79 Ok(v) => v.into(),
80 Err(error) => error.to_compile_error().into(),
81 }
82}
83
84#[proc_macro_derive(FromRow)]
85pub fn derive_from_row(input: TokenStream) -> TokenStream {
86 let item = parse_macro_input!(input as ItemStruct);
87 let doc = match pyro_macro::format::documentation::generate_documented_impl(
88 &item,
89 &parse_quote!(::pyroduct),
90 DocRec::NoReq,
91 ) {
92 Ok(v) => v,
93 Err(error) => return error.to_compile_error().into(),
94 };
95 let from = match pyro_macro::format::from_row::from_row(&item, &parse_quote!(::pyroduct)) {
96 Ok(v) => v,
97 Err(error) => return error.to_compile_error().into(),
98 };
99 quote! {
100 #doc
101 #from
102 }
103 .into()
104}
105
106#[proc_macro_derive(RefFromRow)]
107pub fn derive_ref_from_row(input: TokenStream) -> TokenStream {
108 let item = parse_macro_input!(input as ItemStruct);
109 let doc = match pyro_macro::format::documentation::ref_documentation(
110 &item,
111 &parse_quote!(::pyroduct),
112 DocRec::NoReq,
113 ) {
114 Ok(v) => v,
115 Err(error) => return error.to_compile_error().into(),
116 };
117 let from = match pyro_macro::format::from_row::ref_from_row(&item, &parse_quote!(::pyroduct)) {
118 Ok(v) => v,
119 Err(error) => return error.to_compile_error().into(),
120 };
121 quote! {
122 #doc
123 #from
124 }
125 .into()
126}
127
128#[proc_macro_derive(ToRow)]
129pub fn derive_to_row(input: TokenStream) -> TokenStream {
130 let item = parse_macro_input!(input as ItemStruct);
131 match pyro_macro::format::to_row::to_row(&item, &parse_quote!(::pyroduct)) {
132 Ok(v) => v.into(),
133 Err(error) => error.to_compile_error().into(),
134 }
135}
136
137#[proc_macro_attribute]
138pub fn capability(_args: TokenStream, input: TokenStream) -> TokenStream {
139 let item = parse_macro_input!(input as syn::ItemImpl);
140 let name = std::env::var("CARGO_PKG_NAME").unwrap_or_else(|_| "unknown".to_string());
141 let version = std::env::var("CARGO_PKG_VERSION").unwrap_or_else(|_| "0.0.0".to_string());
142
143 match pyro_macro::ffi::capability::CapabilityImpl::new(item, false, &name, &version) {
144 Ok(cap) => cap.expand_capability().into(),
145 Err(e) => e.to_compile_error().into(),
146 }
147}
148
149#[proc_macro_attribute]
150pub fn config(_args: TokenStream, input: TokenStream) -> TokenStream {
151 let item = parse_macro_input!(input as syn::ItemStruct);
152 match pyro_macro::ffi::config::CapConfig::new(item, DocRec::NoReq) {
153 Ok(cfg) => cfg.expand().into(),
154 Err(e) => e.to_compile_error().into(),
155 }
156}
157
158#[proc_macro_attribute]
159pub fn module(attr: TokenStream, item: TokenStream) -> TokenStream {
160 let attrs: pyro_macro::module::ModuleAttrs = match parse2(attr.into()) {
161 Ok(attrs) => attrs,
162 Err(error) => return error.to_compile_error().into(),
163 };
164 let input_fn: ItemFn = match parse2(item.into()) {
165 Ok(attrs) => attrs,
166 Err(error) => return error.to_compile_error().into(),
167 };
168 if attrs.session {
169 pyro_macro::module::expand_session(attrs, input_fn)
170 .unwrap_or_else(|e| e.to_compile_error())
171 .into()
172 } else {
173 pyro_macro::module::expand(attrs, input_fn)
174 .unwrap_or_else(|e| e.to_compile_error())
175 .into()
176 }
177}