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