1#![warn(clippy::all)]
5use dft::expand_helmholtz_energy_functional;
6use functional_contribution::expand_functional_contribution;
7use ideal_gas::expand_ideal_gas;
8use proc_macro::TokenStream;
9use residual::expand_residual;
10use subset::expand_subset;
11use syn::{parse_macro_input, DeriveInput};
12
13mod dft;
14mod functional_contribution;
15mod ideal_gas;
16mod residual;
17mod subset;
18
19const OPT_IMPLS: [&str; 7] = [
21 "molar_weight",
22 "parameter_info",
23 "entropy_scaling",
24 "functional",
25 "bond_lengths",
26 "fluid_parameters",
27 "pair_potential",
28];
29
30fn implement(name: &str, variant: &syn::Variant, opts: &[&'static str]) -> syn::Result<bool> {
31 let syn::Variant { attrs, .. } = variant;
32 let mut implement = Ok(false);
33 for attr in attrs.iter() {
34 if attr.path.is_ident("implement") {
35 if let Ok(syn::Meta::List(list)) = attr.parse_meta() {
36 for meta in list.nested {
37 if let syn::NestedMeta::Meta(syn::Meta::Path(path)) = meta {
38 if !opts.iter().any(|s| path.is_ident(s)) {
40 let opts = opts.join(", ");
41 return Err(syn::Error::new_spanned(
42 path,
43 format!("expected one of: {opts}"),
44 ));
45 }
46
47 if path.is_ident(name) {
49 implement = Ok(true)
50 }
51 }
52 }
53 } else {
54 return Err(syn::Error::new_spanned(
55 &attr.tokens,
56 "expected 'implement(optional_trait, ...)'",
57 ));
58 }
59 }
60 }
61 implement
62}
63
64#[proc_macro_derive(Subset)]
65pub fn derive_components(input: TokenStream) -> TokenStream {
66 let input = parse_macro_input!(input as DeriveInput);
67 expand_subset(input)
68 .unwrap_or_else(syn::Error::into_compile_error)
69 .into()
70}
71
72#[proc_macro_derive(IdealGas)]
73pub fn derive_ideal_gas(input: TokenStream) -> TokenStream {
74 let input = parse_macro_input!(input as DeriveInput);
75 expand_ideal_gas(input)
76 .unwrap_or_else(syn::Error::into_compile_error)
77 .into()
78}
79
80#[proc_macro_derive(ResidualDyn, attributes(implement))]
81pub fn derive_residual(input: TokenStream) -> TokenStream {
82 let input = parse_macro_input!(input as DeriveInput);
83 expand_residual(input)
84 .unwrap_or_else(syn::Error::into_compile_error)
85 .into()
86}
87
88#[proc_macro_derive(HelmholtzEnergyFunctionalDyn, attributes(implement))]
89pub fn derive_helmholtz_energy_functional(input: TokenStream) -> TokenStream {
90 let input = parse_macro_input!(input as DeriveInput);
91 expand_helmholtz_energy_functional(input)
92 .unwrap_or_else(syn::Error::into_compile_error)
93 .into()
94}
95
96#[proc_macro_derive(FunctionalContribution)]
97pub fn derive_functional_contribution(input: TokenStream) -> TokenStream {
98 let input = parse_macro_input!(input as DeriveInput);
99 expand_functional_contribution(input)
100 .unwrap_or_else(syn::Error::into_compile_error)
101 .into()
102}