use proc_macro::TokenStream;
use syn::{Data, DeriveInput, parse_macro_input};
mod deserialization_impl;
mod enum_impl;
mod imports;
mod metadata;
mod newtype_impl;
mod struct_impl;
mod surreal_value_impl;
mod union_impl;
mod validate_impl;
#[derive(Clone, Copy)]
pub(crate) enum PipelineKind {
Both,
Typesync,
Schemasync,
}
impl PipelineKind {
pub fn reaches_database(self) -> bool {
matches!(self, PipelineKind::Both | PipelineKind::Schemasync)
}
pub fn typesync_part(self) -> Option<PipelineKind> {
match self {
PipelineKind::Both | PipelineKind::Typesync => Some(PipelineKind::Typesync),
PipelineKind::Schemasync => None,
}
}
pub fn schemasync_part(self) -> Option<PipelineKind> {
match self {
PipelineKind::Both | PipelineKind::Schemasync => Some(PipelineKind::Schemasync),
PipelineKind::Typesync => None,
}
}
pub fn to_tokens(self) -> proc_macro2::TokenStream {
use quote::quote;
match self {
PipelineKind::Both => quote! { ::evenframe::types::Pipeline::Both },
PipelineKind::Typesync => quote! { ::evenframe::types::Pipeline::Typesync },
PipelineKind::Schemasync => quote! { ::evenframe::types::Pipeline::Schemasync },
}
}
}
fn typesync_warnings(input: &DeriveInput) -> proc_macro2::TokenStream {
evenframe_core::derive::typesync_attributes::warnings(input)
}
#[proc_macro_derive(
Evenframe,
attributes(
evenframe,
edge,
define_field_statement,
format,
permissions,
mock_data,
morphs,
validators,
relation,
event,
doccom,
unique,
index,
indexes,
fulltext,
hnsw,
diskann,
surreal,
schemasync,
typesync
)
)]
pub fn evenframe_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let warnings = typesync_warnings(&input);
let tokens = match input.data {
Data::Struct(_) => struct_impl::generate_struct_impl(input, PipelineKind::Both),
Data::Enum(_) => enum_impl::generate_enum_impl(input, PipelineKind::Both),
_ => syn::Error::new(
input.ident.span(),
"Evenframe can only be used on structs and enums",
)
.to_compile_error(),
};
quote::quote! { #tokens #warnings }.into()
}
#[proc_macro_derive(EvenframeUnion, attributes(typesync))]
pub fn evenframe_union_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let warnings = typesync_warnings(&input);
let tokens = match input.data {
Data::Enum(_) => union_impl::generate_union_impl(input),
_ => syn::Error::new(
input.ident.span(),
"EvenframeUnion can only be used on enums",
)
.to_compile_error(),
};
quote::quote! { #tokens #warnings }.into()
}
#[proc_macro_derive(SurrealValue, attributes(serde, surreal))]
pub fn surreal_value_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let mode = surreal_value_impl::Mode::Row;
let tokens =
evenframe_core::derive::naming::resolve(&input).and_then(|wire| match input.data {
Data::Struct(_) => surreal_value_impl::struct_surreal_value(&input, &wire, mode, &[]),
Data::Enum(_) => surreal_value_impl::enum_surreal_value(&input, &wire, mode),
Data::Union(_) => Err(syn::Error::new(
input.ident.span(),
"SurrealValue can only be derived for structs and enums",
)),
});
tokens.unwrap_or_else(syn::Error::into_compile_error).into()
}
#[proc_macro_derive(
Typesync,
attributes(
evenframe,
edge,
define_field_statement,
format,
permissions,
mock_data,
morphs,
validators,
relation,
event,
doccom,
unique,
index,
indexes,
fulltext,
hnsw,
diskann,
surreal,
schemasync,
typesync
)
)]
pub fn typesync_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let warnings = typesync_warnings(&input);
let tokens = match input.data {
Data::Struct(_) => struct_impl::generate_struct_impl(input, PipelineKind::Typesync),
Data::Enum(_) => enum_impl::generate_enum_impl(input, PipelineKind::Typesync),
_ => syn::Error::new(
input.ident.span(),
"Typesync can only be used on structs and enums",
)
.to_compile_error(),
};
quote::quote! { #tokens #warnings }.into()
}
#[proc_macro_derive(
Schemasync,
attributes(
evenframe,
edge,
define_field_statement,
format,
permissions,
mock_data,
morphs,
validators,
relation,
event,
doccom,
unique,
index,
indexes,
fulltext,
hnsw,
diskann,
surreal,
schemasync,
typesync
)
)]
pub fn schemasync_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let warnings = typesync_warnings(&input);
let tokens = match input.data {
Data::Struct(_) => struct_impl::generate_struct_impl(input, PipelineKind::Schemasync),
Data::Enum(_) => enum_impl::generate_enum_impl(input, PipelineKind::Schemasync),
_ => syn::Error::new(
input.ident.span(),
"Schemasync can only be used on structs and enums",
)
.to_compile_error(),
};
quote::quote! { #tokens #warnings }.into()
}