pro_serde_versioned/lib.rs
1// ┌───────────────────────────────────────────────────────────────────────────┐
2// │ │
3// │ ██████╗ ██████╗ ██████╗ Copyright (C) The Prospective Company │
4// │ ██╔══██╗██╔══██╗██╔═══██╗ All Rights Reserved - April 2022 │
5// │ ██████╔╝██████╔╝██║ ██║ │
6// │ ██╔═══╝ ██╔══██╗██║ ██║ Proprietary and confidential. Unauthorized │
7// │ ██║ ██║ ██║╚██████╔╝ copying of this file, via any medium is │
8// │ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ strictly prohibited. │
9// │ │
10// └───────────────────────────────────────────────────────────────────────────┘
11
12#![doc = include_str!("../README.md")]
13
14mod formats;
15
16#[cfg(feature = "derive")]
17pub use pro_serde_versioned_derive::{VersionedDeserialize, VersionedSerialize, VersionedUpgrade};
18use serde::{Deserialize, Serialize};
19
20pub use crate::formats::*;
21
22/// Derivable trait used to chain upgrade a versioned wrapper to the latest
23/// version of a structure (e.g. v1 -> v2 -> ... -> latest)
24pub trait VersionedUpgrade {
25 type Latest;
26 fn upgrade_to_latest(self) -> Self::Latest;
27}
28
29/// Defines the next version of a given upgradable type (e.g. mystructv1 ->
30/// mystructv1)
31pub trait Upgrade<To> {
32 fn upgrade(self) -> To;
33}
34
35/// Allows for serializing to any supported format.
36pub trait VersionedSerialize {
37 type VersionedEnvelope<F: Serialize>: Serialize;
38
39 fn to_envelope<F>(&self) -> Result<Self::VersionedEnvelope<F>, F::Error>
40 where
41 F: SerializeFormat;
42
43 fn versioned_serialize<F>(&self) -> Result<F, F::Error>
44 where
45 F: SerializeFormat,
46 {
47 Ok(F::serialize_format(self.to_envelope::<F>()?)?)
48 }
49}
50
51/// Allows for serializing from any supported format.
52pub trait VersionedDeserialize: Sized + Clone {
53 type VersionedEnvelope<'a, F: Deserialize<'a>>: Deserialize<'a>;
54
55 fn from_envelope<'a, F>(data: &Self::VersionedEnvelope<'a, F>) -> Result<Self, F::Error>
56 where
57 F: DeserializeFormat + Deserialize<'a>;
58
59 fn versioned_deserialize<'a, F>(data: &'a F) -> Result<Self, F::Error>
60 where
61 F: DeserializeFormat + Deserialize<'a>,
62 {
63 let envelope: Self::VersionedEnvelope<'a, F> = F::deserialize_format(data)?;
64 Self::from_envelope(&envelope)
65 }
66}
67
68/// Serialize to the underlying format of a given serialization standard. (e.g.
69/// [serde_json::Value] for JSON, [std::borrow::Cow] of bytes for MsgPack, etc.)
70pub trait SerializeFormat: Sized + Serialize {
71 type Error: serde::ser::Error;
72 fn serialize_format<T>(data: T) -> Result<Self, Self::Error>
73 where
74 T: Serialize;
75}
76
77/// Deserialize from the underlying format of a given serialization standard.
78/// (e.g. [serde_json::Value] for JSON, [std::borrow::Cow] of bytes for MsgPack,
79/// etc.)
80pub trait DeserializeFormat: Sized {
81 type Error: serde::de::Error;
82 fn deserialize_format<'a, T>(&'a self) -> Result<T, Self::Error>
83 where
84 T: Deserialize<'a>;
85}
86
87/// Versioned wrapper for the underlying data format.
88/// Allows for partial deserialization of the data, and for
89/// the version number to be used to determine which
90/// deserialization method to use.
91#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
92pub struct VersionedEnvelope<T> {
93 pub version_number: usize,
94 pub data: T,
95}