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}