1#![allow(unused)]
2#![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
62fn 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}