3 stable releases
new 1.0.2 | Dec 15, 2024 |
---|---|
1.0.1 | Dec 14, 2024 |
#270 in Encoding
331 downloads per month
135KB
2.5K
SLoC
Dyn Serde
This crate provides support for dynamic serialization and deserialization based on serde
.
Overview
This crate provides three dyn-compatible version of the serde
traits:
-
Serialize
- dyn-compatible version ofserde::Serialize
:- Implementing
serde::Serialize
will automatically provides an implementation ofSerialize
; - The trait object
dyn Serialize
also implementsserde::Serialize
;
- Implementing
-
Serializer
- dyn-compatible version ofserde::Serializer
:- Instance of
Serializer
can be converted from instance ofserde::Serializer
by method<dyn Serializer>::new
; - The trait object
dyn Serializer
also implementsserde::Serializer
;
- Instance of
-
Deserializer
- dyn-compatible version ofserde::Deserializer
:- Instance of
Deserializer
can be converted from instance ofserde::Deserializer
by method<dyn Deserializer>::new
; - The trait object
dyn Deserializer
also implementsserde::Deserializer
;
- Instance of
Examples
Serialization
Following example demonstrates how to perform serialization with a dynamic serializer:
use serde::Serialize
use dyn_serde::Serializer;
// 1. Creates dynamic serializer using `<dyn Serializer>::new`.
let mut buffer = Vec::with_capacity(64);
let mut serializer = serde_json::Serializer::new(std::io::Cursor::new(&mut buffer));
let mut serializer = <dyn Serializer>::new(&mut serializer);
let serializer: &mut dyn Serializer = &mut serializer;
// 2. Just uses the dynamic serializer as a `serde::Serializer`.
let value = "Hello, world!";
value.serialize(serializer).unwrap();
assert_eq!(buffer, b"\"Hello, world!\"");
Deserialization
Following example demonstrates how to perform deserialization with a dynamic deserializer, which is basically the same as serialization:
use serde::Deserialize;
use dyn_serde::Deserializer;
// 1. Creates dynamic deserializer using `<dyn Deserializer>::new`.
let mut deserializer = serde_json::Deserializer::from_str("\"Hello, world!\"");
let mut deserializer = <dyn Deserializer>::new(&mut deserializer);
let deserializer: &mut dyn Deserializer = &mut deserializer;
// 2. Just uses the dynamic deserializer as a `serde::Deserializer`.
let value = String::deserialize(deserializer).unwrap();
assert_eq!(value, "Hello, world!");
Comparison with erased-serde
This crate (dyn_serde
) is aimed at learning erased_serde
, which is licensed under either of Apache License, Version 2.0 or MIT license.
And dyn_serde
has made many improvements:
-
dyn_serde
supports "no-std" and "no-alloc". -
In the deserialization
erased_serde
uses a carefully maintained objectAny
to represent the deserialized value, which may need to perform memory management (and produces a lot of unsafe codes). Butdyn_serde
performs in-place deserialization and does not need any memory allocation. -
Based to the above improvements,
dyn_serde
gets rid of all unsafe codes. -
……
Also, there are still some unimplemented functionalities:
-
The serialization result (
Serializer::Ok
) cannot be accessed by the dynamic serializer.Note, if the serializer is known to be
MakeSerializer<S>
, the methodexpect
could help. -
erased_serde
provides macroserialize_trait_object!
for implementingserde::Serialize
for trait objects. -
dyn_serde
needs more detailed error messages. -
……
Performance
bench/de.rs
is a simple benchmark that tests the deserialization performance of serde_json
(version 0.4.5, default features), erased-serde
(version 1.0.133, default features) and dyn_serde
(version 1.0.1, default features).
-
benchmark tool:
criterion.rs
. -
data (twiter.json, ~620 KiB) is from nativejson-benchmark.
-
cargo/rustc: version 1.83.0.
Following output shows, the dynamic deserializer defined in dyn_serde
has much lower overhead (4.0915 / 3.6208 = 1.123
) than erased_serde
(6.4764 / 3.6208 = 1.789
).
$ cargo bench de
serde-json time: [3.5854 ms 3.6208 ms 3.6587 ms]
change: [-0.8127% +0.5305% +1.9817%] (p = 0.47 > 0.05)
No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
dyn-serde time: [4.0693 ms 4.0915 ms 4.1174 ms]
change: [-0.4532% +0.3426% +1.1811%] (p = 0.40 > 0.05)
No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
2 (2.00%) high mild
6 (6.00%) high severe
erased-serde time: [6.4466 ms 6.4764 ms 6.5231 ms]
change: [-0.3880% +0.1163% +0.9587%] (p = 0.77 > 0.05)
No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high severe
No-std support
To opt off the Rust standard library, you can disable feature std
:
dyn_serde = { version = "*", default-features = false }
If the memory allocation is needed (for example, deserialize_byte_buf
uses Vec<u8>
), you can enable feature alloc
:
dyn_serde = { version = "*", default-features = false, features = ["alloc"] }
NOTE: if both std
and alloc
are disabled, the (de)serialization error would not provide useful error messages!
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Dependencies
~100–325KB