restate_sdk_macros/
lib.rs1extern crate proc_macro;
15
16mod ast;
17mod generator;
18mod struct_ast;
19mod struct_generator;
20
21use crate::ast::{Object, Service, ServiceType, Workflow};
22use crate::generator::ServiceGenerator;
23use crate::struct_ast::StructService;
24use proc_macro::TokenStream;
25use quote::ToTokens;
26use syn::{Item, parse_macro_input};
27
28#[proc_macro_attribute]
29pub fn service(attr: TokenStream, input: TokenStream) -> TokenStream {
30 dispatch(ServiceType::Service, attr, input)
31}
32
33#[proc_macro_attribute]
34pub fn object(attr: TokenStream, input: TokenStream) -> TokenStream {
35 dispatch(ServiceType::Object, attr, input)
36}
37
38#[proc_macro_attribute]
39pub fn workflow(attr: TokenStream, input: TokenStream) -> TokenStream {
40 dispatch(ServiceType::Workflow, attr, input)
41}
42
43#[proc_macro_attribute]
48pub fn handler(_: TokenStream, input: TokenStream) -> TokenStream {
49 input
50}
51
52fn dispatch(service_ty: ServiceType, attr: TokenStream, input: TokenStream) -> TokenStream {
55 let item = parse_macro_input!(input as Item);
56 match item {
57 Item::Impl(item_impl) => {
58 let args = match struct_ast::parse_service_args(attr.into(), service_ty) {
59 Ok(args) => args,
60 Err(e) => return e.to_compile_error().into(),
61 };
62 match StructService::from_impl(service_ty, args, item_impl) {
63 Ok(svc) => struct_generator::generate(&svc).into(),
64 Err(e) => e.to_compile_error().into(),
65 }
66 }
67 Item::Trait(item_trait) => {
68 let tokens = item_trait.into_token_stream();
70 let result = match service_ty {
71 ServiceType::Service => syn::parse2::<Service>(tokens)
72 .map(|s| ServiceGenerator::new_service(&s).into_token_stream()),
73 ServiceType::Object => syn::parse2::<Object>(tokens)
74 .map(|s| ServiceGenerator::new_object(&s).into_token_stream()),
75 ServiceType::Workflow => syn::parse2::<Workflow>(tokens)
76 .map(|s| ServiceGenerator::new_workflow(&s).into_token_stream()),
77 };
78 match result {
79 Ok(ts) => ts.into(),
80 Err(e) => e.to_compile_error().into(),
81 }
82 }
83 other => syn::Error::new_spanned(
84 other,
85 "#[restate_sdk::service]/#[object]/#[workflow] can only be applied to a trait \
86 (deprecated) or an inherent impl block",
87 )
88 .to_compile_error()
89 .into(),
90 }
91}