1use darling::FromDeriveInput;
2use syn::parse_macro_input;
3
4use crate::attrs::{ContainerAttrs, extract_container_attr_spans};
5use crate::config::MacroConfig;
6use crate::context::MacroContext;
7
8mod attrs;
9mod build_schema;
10pub(crate) mod config;
11pub(crate) mod context;
12mod from_eure;
13mod into_eure;
14mod must_be_text;
15mod util;
16
17#[proc_macro_derive(IntoEure, attributes(eure))]
18pub fn into_eure_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
19 let input = parse_macro_input!(input as syn::DeriveInput);
20 match create_context(input) {
21 Ok(context) => into_eure::derive(context).into(),
22 Err(err) => err.to_compile_error().into(),
23 }
24}
25
26#[proc_macro_derive(FromEure, attributes(eure))]
27pub fn from_eure_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
28 let input = parse_macro_input!(input as syn::DeriveInput);
29 match create_context(input) {
30 Ok(context) => from_eure::derive(context).into(),
31 Err(err) => err.to_compile_error().into(),
32 }
33}
34
35#[proc_macro_derive(BuildSchema, attributes(eure))]
36pub fn build_schema_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
37 let input = parse_macro_input!(input as syn::DeriveInput);
38 match create_context(input) {
39 Ok(context) => build_schema::derive(context).into(),
40 Err(err) => err.to_compile_error().into(),
41 }
42}
43
44fn create_context(input: syn::DeriveInput) -> syn::Result<MacroContext> {
45 let attrs = ContainerAttrs::from_derive_input(&input).expect("Failed to parse eure attributes");
46 let attr_spans = extract_container_attr_spans(&input);
47 let mut config = MacroConfig::from_attrs(attrs, attr_spans)?;
48 if has_non_exhaustive_attr(&input.attrs) {
49 config.non_exhaustive = true;
50 }
51 Ok(MacroContext::new(config, input))
52}
53
54fn has_non_exhaustive_attr(attrs: &[syn::Attribute]) -> bool {
55 attrs
56 .iter()
57 .any(|attr| attr.path().is_ident("non_exhaustive"))
58}
59
60#[proc_macro]
79#[allow(non_snake_case)]
80pub fn MustBeText(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
81 let input = parse_macro_input!(input as must_be_text::MustBeTextInput);
82 must_be_text::expand(input).into()
83}