A Serde implementation for the RESP (Redis Serialization Protocol) format, supporting both serialization and deserialization of Rust data structures.
- Serialize Rust types to RESP format
- Deserialize RESP data into Rust types
- Supports complex structs, enums, maps, arrays, options, and more
- Simple API:
to_string,to_bytes,from_str,from_bytes - Full support of serde's derive macros
- Supports all RESP2 and RESP3 data types
cargo add serde --features derive
cargo add rediserdeOr add to your Cargo.toml:
[dependencies]
rediserde = "0.1.0"
serde = { version = "1.0", features = ["derive"] }Note
derive feature is optional but recommended for ease of use (with #[derive(Serialize, Deserialize)])
Use this crate like any other serde-compatible crate (like serde_json or serde_yaml):
use rediserde::{from_str, to_string};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Person {
name: String,
age: u32,
}
let person = Person {
name: "Alice".to_string(),
age: 30,
let serialized = to_string(&person).unwrap();
let deserialized: Person = from_str(&serialized).unwrap();
let deserialized_raw: Person = from_str("%2\r\n+name\r\n+Alice\r\n+age\r\n:30\r\n").unwrap();
assert_eq!(deserialized, person);
assert_eq!(deserialized_raw, person);For a more complex example, see the tests/structs.rs file.
- Full docs: docs.rs/rediserde.
- Repository: github.com/ofersadan85/rediserde.
- Crate: crates.io/crates/rediserde.
For more details on how to use this crate, refer to the Serde documentation.
This crate supports the full RESP2 + RESP3 protocol specification, including:
- Simple strings, errors, integers, bulk strings, arrays, maps, sets, nulls, booleans, floats (doubles), big numbers, verbatim strings, and more.
However, to match with Rust's (and serde's) types the mapping is roughly as follows:
| RESP Type | Rust Type |
|---|---|
| Simple String | String |
| Error | String |
| Integer | u8-u32, i8-i64 |
| Bulk String | String |
| Array | Vec<T> |
| Null | Option<T> (None) |
| Boolean | bool |
| Double | f64 |
| Big Number | u64 & usize |
| Verbatim String | String |
| Map | HashMap<String, T> |
| Attribute | HashMap<String, T> |
| Set | Vec<T> |
| Push | Vec<T> |
However, since the mapping is not one-to-one, there are some important notes:
- RESP
Integers are deserializable to any Rust integer numeric type, assuming they fit within the range of the target type. - RESP
Big Numbers are deserializable to all "smaller" Rust integer types assuming they fit within the range of the target type, but RESPIntegeris at mosti64, so a Rustu64(which might be bigger) will always be serialized as aBig Numberwhile other numeric integer types will be serialized as RESPIntegers. - RESP
Doubles (floating point numbers) are deserializable to bothf64andf32, assuming they fit within the range of the target type. - RESP
Maps andAttributes are both deserializable into structs, andHashMaps but structs andHashMaps are always serialized as RESPMaps. - RESP
Arrays,Sets, andPushes are deserializable into any Rust sequence type (likeVec,HashSet, etc.) but Rust sequences are always serialized as RESPArrays. - RESP's various string types (
Simple String,Simple Error,Bulk String,Bulk Error,Verbatim String) are deserializable into a RustString, but RustStrings are always serialized as RESPBulk String(as this is the most common and versatile string type in RESP). - Rust
Strings are guaranteed to be UTF-8 encoded, but RESP types are not, so deserializing will fail if the RESP data is not valid UTF-8. If you're unsure, deserialize to bytes (Vec<u8>) instead and handle the data manually. - Rust's
u128andi128are not supported by serde. If support is added there, we will follow and they will have to be serialized as RESPBig Numbers. - Rust does not support any primitive
Nulltype, so creating a RESPNullis only possible in the context of anOption<T>whereTis any type. TheNonevariant will be serialized as RESPNulland vice versa. - RESP concepts like a Null Array or Null String are not easily representable in Rust, but reading such a value will not fail but yield an empty array or an empty string, respectively.
- While RESP supports maps and arrays with mixed types, Rust does not, so trying to get a Rust
HashMap<String, T>orVec<T>with mixed types will fail. - Currently, only
Strings are supported as map keys (although RESP supports any type). This is planned to be extended in the future to support more types, but only as far as is reasonable for Rust, i.e. types that implement theHashandEqtraits as required byHashMap.
- serde-RESP: A similar crate that also implements RESP serialization and deserialization with serde, but with a different API and design choices. Unlike this crate, it does not directly support serde's derive macros on enums and structs, but has some handy macros for direct data manipulation. Appears to be unmaintained since February 2021. GitHub.
- resp: A crate for RESP types. Does not integrate with serde. It provides a low-level API for working with RESP data, but does not support serialization or deserialization of Rust types. Appears to be unmaintained since August 2022. GitHub.
- stream_resp: A crate that provides a streaming API for RESP data, but does not support serde serialization or deserialization. Appears to be actively maintained. GitHub.
To try and minimize dependencies and maximize flexibility in further development, this crate does not depend on any of the above crates, but rather implements RESP serialization and deserialization directly.
- This crate is in active development, and tries to choose the most sensible defaults, which might not perfectly match your use case. We plan to implement more serializers and deserializers if there's demand (or perhaps, enable crate features), so please open an issue if you need a specific feature or behavior.
- Contributions are welcome!
- The RESP protocol is designed for Redis, so some features might not be applicable outside of that context. This crate is primarily intended for use with Redis or similar systems that use the RESP protocol.
- Performance has not been well tested, yet. If you want to help with that, please open an issue or a PR.
- This crate is provided "as is" without any warranties or guarantees. Use it at your own risk.