extern crate proc_macro;
mod ast;
mod generator;
mod struct_ast;
mod struct_generator;
use crate::ast::{Object, Service, ServiceType, Workflow};
use crate::generator::ServiceGenerator;
use crate::struct_ast::StructService;
use proc_macro::TokenStream;
use quote::ToTokens;
use syn::{Item, parse_macro_input};
#[proc_macro_attribute]
pub fn service(attr: TokenStream, input: TokenStream) -> TokenStream {
dispatch(ServiceType::Service, attr, input)
}
#[proc_macro_attribute]
pub fn object(attr: TokenStream, input: TokenStream) -> TokenStream {
dispatch(ServiceType::Object, attr, input)
}
#[proc_macro_attribute]
pub fn workflow(attr: TokenStream, input: TokenStream) -> TokenStream {
dispatch(ServiceType::Workflow, attr, input)
}
#[proc_macro_attribute]
pub fn handler(_: TokenStream, input: TokenStream) -> TokenStream {
input
}
fn dispatch(service_ty: ServiceType, attr: TokenStream, input: TokenStream) -> TokenStream {
let item = parse_macro_input!(input as Item);
match item {
Item::Impl(item_impl) => {
let args = match struct_ast::parse_service_args(attr.into(), service_ty) {
Ok(args) => args,
Err(e) => return e.to_compile_error().into(),
};
match StructService::from_impl(service_ty, args, item_impl) {
Ok(svc) => struct_generator::generate(&svc).into(),
Err(e) => e.to_compile_error().into(),
}
}
Item::Trait(item_trait) => {
let tokens = item_trait.into_token_stream();
let result = match service_ty {
ServiceType::Service => syn::parse2::<Service>(tokens)
.map(|s| ServiceGenerator::new_service(&s).into_token_stream()),
ServiceType::Object => syn::parse2::<Object>(tokens)
.map(|s| ServiceGenerator::new_object(&s).into_token_stream()),
ServiceType::Workflow => syn::parse2::<Workflow>(tokens)
.map(|s| ServiceGenerator::new_workflow(&s).into_token_stream()),
};
match result {
Ok(ts) => ts.into(),
Err(e) => e.to_compile_error().into(),
}
}
other => syn::Error::new_spanned(
other,
"#[restate_sdk::service]/#[object]/#[workflow] can only be applied to a trait \
(deprecated) or an inherent impl block",
)
.to_compile_error()
.into(),
}
}