#[derive(Deserialize)]
{
// Attributes available to this derive:
#[serde]
#[eserde]
}
Expand description
A derive macro to automatically implement EDeserialize and serde::Deserialize for a type.
§Example
// 👇 `eserde`'s derive
#[derive(serde::Serialize, eserde::Deserialize)]
struct Point {
x: f64,
y: f64,
}§Common issues
Using both #[derive(eserde::Deserialize)] and #[derive(serde::Deserialize)] on the same type
will cause a compilation error:
// 🚫 Won't compile
#[derive(eserde::Deserialize, serde::Deserialize)]
struct Point {
x: f64,
y: f64,
}The compilation error is a variation of the following:
error[E0119]: conflicting implementations of trait `Deserialize<'_>` for type `Point`
--> my_module.rs
|
| #[derive(eserde::Deserialize, serde::Deserialize)]
| ------------------- ^^^^^^^^^^^^^^^^^^ conflicting implementation for `Point`
| |
| first implementation here
|
= note: this error originates in the derive macro `serde::Deserialize`§Customizing the deserialization process
You can use serde attributes to control how your type
is deserialized.
#[derive(eserde::Deserialize)]
struct Point {
#[serde(rename = "latitude")]
x: f64,
#[serde(rename = "longitude")]
y: f64,
}eserde will pick up those attributes and honor their contracts.
§Interoperability
eserde::Deserialize expects all fields in your type to implement eserde::EDeserialize.
If that’s not the case, there will be a compilation error.
Consider this example:
#[derive(eserde::Deserialize)]
struct Point {
x: Latitude,
y: Longitude,
}
// 👇 Plain serde!
#[derive(serde::Deserialize)]
struct Latitude(f64);
#[derive(eserde::Deserialize)]
struct Longitude(f64);It’ll fail to compile with the following error:
error[E0277]: the trait bound `Latitude: EDeserialize<'_>` is not satisfied
|
| #[derive(eserde::Deserialize)]
| ^^^^^^^^^^^^^^^^^^^
| the trait `EDeserialize<'_>` is not implemented for `Latitude`If Latitude is defined in one of your crates, you can fix the issue by replacing #[derive(serde::Deserialize)]
with #[derive(eserde::Deserialize)] on its definition.
That may not always be possible, though—e.g. Latitude may come from a third-party crate that doesn’t support
eserde yet.
You can bypass the issue using the #[eserde(compat)] attribute:
#[derive(eserde::Deserialize)]
struct Point {
// 👇 New attribute!
#[eserde(compat)]
x: Latitude,
y: Longitude,
}
#[derive(serde::Deserialize)]
struct Latitude(f64);
#[derive(eserde::Deserialize)]
struct Longitude(f64);#[eserde(compat)] instructs eserde to use serde’s deserialization logic for Latitude when
collecting errors. It now compiles!
There’s a catch, though: you’ll get at most one deserialization error from a field annotated
with #[eserde(compat)], since we can’t rely on EDeserialize’s error machinery.
§Limitations
eserde doesn’t support all serde attributes (yet).
The following container attributes will be rejected at compile-time:
#[serde(untagged)]on enums#[serde(default)]#[serde(remote = "...")]#[serde(try_from = "...")]#[serde(from = "...")]#[serde(bound = "...")]#[serde(variant_identifier)]#[serde(field_identifier)]
The following variant attributes will be rejected at compile-time:
#[serde(skip_deserializing)]#[serde(deserialize_with = "...")]#[serde(with = "...")]#[serde(bound = "...")]#[serde(untagged)]
The following field attributes will be rejected at compile-time:
#[serde(skip_deserializing)]#[serde(bound = "...")]
We plan to support most of these attributes in the future.