redis_om_macros/
lib.rs

1#![allow(unused)]
2//! Derive proc macros for redis-om crate
3#![deny(unstable_features)]
4
5mod ast;
6mod derive;
7mod ext;
8mod util;
9
10use ast::{Container, Ctx};
11use derive::*;
12use proc_macro::TokenStream;
13use quote::quote;
14use syn::{parse_macro_input, Data::*, DeriveInput};
15
16#[proc_macro_derive(HashModel, attributes(redis))]
17pub fn hash_model(attr: TokenStream) -> TokenStream {
18    let input = parse_macro_input!(attr as DeriveInput);
19    match into_container(&input) {
20        Ok((ctx, cont)) => into_stream(hash_model::derive(&ctx, &cont), ctx),
21        Err(value) => return value,
22    }
23}
24
25#[cfg(feature = "json")]
26#[proc_macro_derive(JsonModel, attributes(redis))]
27pub fn json_model(attr: TokenStream) -> TokenStream {
28    let input = parse_macro_input!(attr as DeriveInput);
29    match into_container(&input) {
30        Ok((ctx, cont)) => into_stream(json_model::derive(&ctx, &cont), ctx),
31        Err(value) => return value,
32    }
33}
34
35#[proc_macro_derive(RedisModel, attributes(redis))]
36pub fn redis_model(attr: TokenStream) -> TokenStream {
37    let input = parse_macro_input!(attr as DeriveInput);
38    match into_container(&input) {
39        Ok((ctx, cont)) => into_stream(redis_model::derive(&ctx, &cont), ctx),
40        Err(value) => return value,
41    }
42}
43
44#[proc_macro_derive(StreamModel, attributes(redis))]
45pub fn stream_model(attr: TokenStream) -> TokenStream {
46    let input = parse_macro_input!(attr as DeriveInput);
47    match into_container(&input) {
48        Ok((ctx, cont)) => into_stream(stream_model::derive(&ctx, &cont), ctx),
49        Err(value) => return value,
50    }
51}
52
53#[proc_macro_derive(RedisTransportValue, attributes(redis))]
54pub fn redis_transport_value(attr: TokenStream) -> TokenStream {
55    let input = parse_macro_input!(attr as DeriveInput);
56    match into_container(&input) {
57        Ok((ctx, cont)) => into_stream(value::derive(&ctx, &cont), ctx),
58        Err(value) => return value,
59    }
60}
61
62// --------------------------------------------------------------------------------------
63// --------------------------------------------------------------------------------------
64
65fn into_stream(stream: Result<proc_macro2::TokenStream, ()>, ctx: Ctx) -> TokenStream {
66    let check = ctx.check();
67    let res = if check.is_err() {
68        into_to_compile_errors(check.unwrap_err())
69    } else {
70        stream.unwrap_or_else(|_| into_to_compile_errors(check.unwrap_err()))
71    };
72    res.into()
73}
74
75fn into_to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream {
76    let compile_errors = errors.iter().map(syn::Error::to_compile_error);
77    quote!(#(#compile_errors)*)
78}
79
80fn into_container(input: &DeriveInput) -> Result<(Ctx, Container<'_>), TokenStream> {
81    let ctx = Ctx::new();
82    let cont = match Container::new(&ctx, input) {
83        Some(cont) => cont,
84        None => return Err(into_to_compile_errors(ctx.check().unwrap_err()).into()),
85    };
86    Ok((ctx, cont))
87}