factrs_proc/
lib.rs

1use syn::{parse_macro_input, ItemImpl};
2
3mod fac;
4mod noise;
5mod residual;
6mod robust;
7mod variable;
8
9enum BoxedTypes {
10    Residual,
11    Variable,
12    Noise,
13    Robust,
14}
15
16fn check_type(input: &ItemImpl) -> syn::Result<BoxedTypes> {
17    let err = syn::Error::new_spanned(input, "Missing trait");
18    let result = &input
19        .trait_
20        .as_ref()
21        .ok_or(err.clone())?
22        .1
23        .segments
24        .last()
25        .ok_or(err)?
26        .ident
27        .to_string();
28
29    if result.contains("Residual") {
30        Ok(BoxedTypes::Residual)
31    } else if result.contains("Variable") {
32        Ok(BoxedTypes::Variable)
33    } else if result.contains("Noise") {
34        Ok(BoxedTypes::Noise)
35    } else if result.contains("Robust") {
36        Ok(BoxedTypes::Robust)
37    } else {
38        Err(syn::Error::new_spanned(input, "Not a valid trait"))
39    }
40}
41
42#[proc_macro_attribute]
43pub fn mark(
44    _args: proc_macro::TokenStream,
45    input: proc_macro::TokenStream,
46) -> proc_macro::TokenStream {
47    let input = syn::parse_macro_input!(input as ItemImpl);
48
49    let trait_type = match check_type(&input) {
50        Ok(syntax_tree) => syntax_tree,
51        Err(err) => return err.to_compile_error().into(),
52    };
53
54    match trait_type {
55        BoxedTypes::Residual => residual::mark(input),
56        BoxedTypes::Variable => variable::mark(input),
57        BoxedTypes::Noise => noise::mark(input),
58        BoxedTypes::Robust => robust::mark(input),
59    }
60    .into()
61}
62
63#[proc_macro]
64pub fn fac(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
65    let factor = parse_macro_input!(input as fac::Factor);
66
67    fac::fac(factor).into()
68}