Using derive
Serde provides a derive macro to generate implementations of the Serialize
and
Deserialize
traits for data structures defined in your crate, allowing them to
be represented conveniently in all of Serde's data formats.
You only need to set this up if your code is using #[derive(Serialize,
Deserialize)]
.
This functionality is based on Rust's #[derive]
mechanism, just like what you
would use to automatically derive implementations of the built-in Clone
,
Copy
, Debug
, or other traits. It is able to generate implementations for
most structs and enums including ones with elaborate generic types or trait
bounds. On rare occasions, for an especially convoluted type you may need to
implement the traits manually.
These derives require a Rust compiler version 1.31 or newer.
Here is the Cargo.toml
:
Cargo.toml
[package]
name = "my-crate"
version = "0.1.0"
authors = ["Me <user@rust-lang.org>"]
[dependencies]
serde = { version = "1.0", features = ["derive"] }
# serde_json is just for the example, not required in general
serde_json = "1.0"
Now the src/main.rs
which uses Serde's custom derives:
src/main.rs
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_json::to_string(&point).unwrap();
println!("serialized = {}", serialized);
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
println!("deserialized = {:?}", deserialized);
}
Here is the output:
$ cargo run
serialized = {"x":1,"y":2}
deserialized = Point { x: 1, y: 2 }
Troubleshooting
Sometimes you may see compile-time errors that tell you:
the trait `serde::ser::Serialize` is not implemented for `...`
even though the struct or enum clearly has #[derive(Serialize)]
on it.
This almost always means that you are using libraries that depend on
incompatible versions of Serde. You may be depending on serde 1.0 in your
Cargo.toml but using some other library that depends on serde 0.9. So the
Serialize
trait from serde 1.0 may be implemented, but the library expects an
implementation of the Serialize
trait from serde 0.9. From the Rust compiler's
perspective these are totally different traits.
The fix is to upgrade or downgrade libraries as appropriate until the Serde
versions match. The cargo tree -d
command is helpful for finding all the
places that duplicate dependencies are being pulled in.