redis-macros
Simple macros and wrappers to redis-rs to automatically serialize and deserialize structs with serde.
Installation
To install it, simply add the package redis-macros
. This package is a helper for redis
and uses serde
and serde_json
(or any other serializer), so add these too to the dependencies.
[]
= "0.4.3"
= { = "0.27" }
= { = "1.0", = ["derive"] }
= { = "1.0" }
Basic usage
Simple usage
The simplest way to start is to derive Serialize
, Deserialize
, FromRedisValue
, ToRedisArgs
for any kind of struct... and that's it! You can now get and set these values with regular redis commands:
use ;
use ;
use ;
// Derive the necessary traits
For more information, see the Basic or Async examples.
Usage with RedisJSON
You can even use it with RedisJSON, to extract separate parts of the object.
// Use `JsonCommands`
use ;
// Derive FromRedisValue, ToRedisArgs to the inner struct
// Simple usage is equivalent to set-get
con.json_set?;
let stored_user: User = con.json_get?;
// But you can get deep values - don't forget to derive traits for these too!
let stored_address: Address = con.json_get?;
For more information, see the RedisJSON example.
One issue you might be facing is that redis
already has overrides for some types, for example Vec, String and most primitives. For this you have to use the Json wrapper.
// This WON'T work
let stored_addresses: = con.json_get?;
Json wrapper with RedisJSON
To deserialize Vecs and primitive types when using RedisJSON, you cannot use the regular types, because these are non-compatible with RedisJSON. However redis-macros
exports a useful wrapper struct: Json
. When using RedisJSON, you can wrap your non-structs return values into this:
use Json;
// Return type can be wrapped into Json
let Json: = con.json_get?;
// It works with Vecs as well
let Json: = con.json_get?;
// ...now stored_addresses will be equal to user.addresses
If you only use RedisJSON, you can even do away with deriving FromRedisValue
and ToRedisArgs
, and use Json
everywhere.
// This works with simple redis-rs
con.json_set?;
// ...and you can get back with Json wrapper
let Json: = con.json_get?;
For more information, see the Json Wrapper and Json Wrapper Advanced examples.
Using other serializer (e.g. serde-yaml)
In case you want to use another serializer, for example serde_yaml
, you can install it and use the derives, the same way you would. The only difference should be adding an attribute redis_serializer
under the derive, with the library you want to serialize with. You can use any Serde serializer as long as they support from_str
and to_string
methods. For the full list, see: Serde data formats.
For more information, see the YAML example.
Using deadpool-redis or other crates
You can still use the macros if you are using a crate that reexports the redis
traits, for example deadpool-redis. The only change you have to make is to use
the reexported redis
package explicitly:
// In the case of deadpool-redis, bring the reexported crate into scope
use redis;
// Or if you are importing multiple things from redis, use redis::self
use ;
For more information, see the deadpool-redis example.
Testing
You can run the unit tests on the code with cargo test
:
For integration testing, you can run the examples. You will need a RedisJSON compatible redis-server on port 6379, redis-stack docker image is recommended:
# cleanup the container
Coverage
For coverage, you can use grcov
. Simply install llvm-tools-preview
and grcov
if you don't have it already:
You have to export a few flags to make it work properly:
And finally, run the tests and generate the output:
Now you can open ./target/debug/coverage/index.html
, and view it in the browser to see the coverage.