derive_redis_json/
lib.rs

1#![recursion_limit = "128"]
2
3#[macro_use]
4extern crate quote;
5
6#[macro_use]
7extern crate syn;
8
9extern crate proc_macro;
10
11use proc_macro::TokenStream;
12use syn::DeriveInput;
13
14#[proc_macro_derive(RedisJsonValue)]
15pub fn redis_json_value(input: TokenStream) -> TokenStream {
16  let input = parse_macro_input!(input as DeriveInput);
17  let struct_type = input.ident;
18
19  let expanded = quote! {
20    impl redis::ToRedisArgs for #struct_type {
21        fn write_redis_args<W>(&self, out: &mut W)
22        where
23          W: ?Sized + redis::RedisWrite,
24        {
25          out.write_arg(&serde_json::to_vec(self).expect("JSON encoding failed"));
26        }
27      }
28      
29      impl redis::FromRedisValue for #struct_type {
30        fn from_redis_value(v: &redis::Value) -> redis::RedisResult<Self> {
31          match *v {
32            redis::Value::Data(ref bytes) => Ok(serde_json::from_slice(bytes).map_err(|err| {
33              (
34                redis::ErrorKind::TypeError,
35                "JSON deserialize failed",
36                err.to_string(),
37              )
38            })?),
39            _ => Err(
40              (
41                redis::ErrorKind::TypeError,
42                "invalid response type for JSON",
43              )
44                .into(),
45            ),
46          }
47        }
48      }
49  };
50
51  TokenStream::from(expanded)
52}