view_types/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use parse::Views;
4use syn::ItemStruct;
5
6mod expand;
7mod parse;
8mod resolve;
9
10/// The main views procedural macro
11/// 
12/// # Example
13/// ```rust
14/// use view_types::views;
15/// 
16/// fn validate_ratio(ratio: &f32) -> bool {
17///     (*ratio >= 0.0 && *ratio <= 1.0)
18/// }
19/// 
20/// #[views(
21///     frag all {
22///         offset,
23///         limit,
24///     }
25///     frag keyword {
26///         Some(query),
27///         words_limit
28///     }
29///     frag semantic {
30///         vector
31///     }
32///     pub view KeywordSearch {
33///         ..all,
34///         ..keyword,
35///     }
36///     pub view SemanticSearch<'a> {
37///         ..all,
38///         ..semantic,
39///     }
40///     pub view HybridSearch<'a> {
41///         ..all,
42///         ..keyword,
43///         ..semantic,
44///         Some(ratio) if validate_ratio(ratio)
45///     }
46/// )]
47/// pub struct Search<'a> {
48///     query: Option<String>,
49///     offset: usize,
50///     limit: usize,
51///     words_limit: Option<usize>,
52///     vector: Option<&'a Vec<u8>>,
53///     ratio: Option<f32>,
54/// }
55/// ```
56#[proc_macro_attribute]
57pub fn views(args: proc_macro::TokenStream, input: proc_macro::TokenStream) -> proc_macro::TokenStream {
58    match views_impl(args, input) {
59        Ok(tokens) => tokens,
60        Err(err) => err.to_compile_error().into(),
61    }
62}
63
64fn views_impl(args: proc_macro::TokenStream, input: proc_macro::TokenStream) -> syn::Result<proc_macro::TokenStream> {
65    let view_spec = syn::parse::<Views>(args.into())?;
66    
67    let mut original_struct = syn::parse::<ItemStruct>(input.into())?;
68    let enum_attributes = crate::parse::extract_nested_attributes("Variant", &mut original_struct.attrs)?;
69    let resolution = resolve::resolve(&original_struct, &view_spec, enum_attributes)?;
70    
71    let generated_code = expand::expand(&original_struct, resolution)?;
72    
73    Ok(quote::quote! {
74        #original_struct
75        #generated_code
76    }.into())
77}