serde-versioning
serde-versioning is a basic Rust crate that implements a naive solution for struct and enum versioning by extending the capabilities of serde_derive. This crate maintains 100% compatibility with serde while introducing a new container attribute versioning that provides versioning support for deserialization.
What it does for you
serde-versioning allows you to turn a versioned struct (or enum) code that might look like this:
use Deserialize;
Into
use Deserialize;
Note: internally serde_versioning doesn't generate an untagged enum.
Features
- Optimistic/Pessimistic Deserialization: Choose whether to attempt deserialization using previous versions first (pessimistic, which is the default) or the latest version first (optimistic).
- Previous Version: Specify a type name (either directly or as a string) representing a previous version.
- Previous Versions: Specify multiple previous versions using an array of type names.
Installation
Add the following to your Cargo.toml:
[]
= { = "https://github.com/vic1707/serde-versioning.git" }
= "1.0.204"
Ensure you have serde listed as a dependency to be able to import the Deserialize trait itself.
Usage
serde-versioning is designed to be a drop-in replacement for serde's Deserialize derive macro. Simply replace:
use Deserialize;
or
use Deserialize;
with
use Deserialize;
And you'll be able to benefit from the versioning attribute while the original Deserialize capabilities stays as is.
Example
In this example, Foo will first attempt to deserialize as FooV0, then as FooV1, and finally as Foo, following the pessimistic strategy.
Feel free to look at the usage example.
Implementation Details
Internally, serde-versioning manually invokes the original derive implementation from serde, which is imported via a git-submodule (synced with serde's tags) to get access to the expand_derive_deserialize function (a PR was proposed to make that function available to anyone #2765 but got refused, submodule will be used until then).
The crate modifies the output to add versioning support, incorporating a few if-let-ok statements to handle the versioning logic.
The implementation is heavily inspired by the untagged enum approach commonly used for versioning, but serde-versioning attempts to make this process more transparent and straightforward.
Basically once derived it looks like this:
Optimistic
Pessimistic
Everything else is left as derived by serde.
If you don't use the new versioning attribute then I simply return what serde derives, nothing less, nothing more.
Contributing
Feel free to open issues or submit pull requests. Contributions are welcome! If you have an opinion on whether we should be pessimistic or optimistic by default I'd love to read your thoughts!
License
This project is licensed under the "Do Whatever the Fuck You Want" License.