revision/
lib.rs

1//! Defines a generic trait for version tolerant serialization and deserialization
2//! and implements it for primitive data types using the `bincode` format.
3//!
4//! The `Revisioned` trait is automatically implemented for the following primitives:
5//! u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64, char,
6//! str, String, Vec<T>, Arrays up to 32 elements, Option<T>, Box<T>, Bound<T>, Wrapping<T>,
7//! (A, B), (A, B, C), (A, B, C, D), (A, B, C, D, E), Duration, HashMap<K, V>,
8//! BTreeMap<K, V>, Result<T, E>, Cow<'_, T>, Decimal, regex::Regex, uuid::Uuid, chrono::Duration,
9//! chrono::DateTime<Utc>, geo::Point, geo::LineString geo::Polygon, geo::MultiPoint,
10//! geo::MultiLineString, and geo::MultiPolygon.
11
12pub mod error;
13pub mod implementations;
14
15pub use crate::error::Error;
16pub use revision_derive::revisioned;
17
18use std::any::TypeId;
19use std::io::{Read, Write};
20
21pub mod prelude {
22	pub use crate::{DeserializeRevisioned, Revisioned, SerializeRevisioned, revisioned};
23}
24
25/// Trait that provides an interface for version aware serialization and deserialization.
26///
27/// Example implementation
28/// ```
29/// use revision::Error;
30/// use revision::prelude::*;
31///
32/// struct MyType<T>(T);
33///
34/// impl<T> SerializeRevisioned for MyType<T>
35/// where
36///    T: SerializeRevisioned,
37/// {
38///    #[inline]
39///   fn serialize_revisioned<W: std::io::Write>(&self, writer: &mut W) -> Result<(), Error> {
40///       self.0.serialize_revisioned(writer)
41///   }
42/// }
43///
44/// impl<T> DeserializeRevisioned for MyType<T>
45/// where
46///    T: DeserializeRevisioned,
47/// {
48///   #[inline]
49///   fn deserialize_revisioned<R: std::io::Read>(reader: &mut R) -> Result<Self, Error> {
50///       Ok(MyType(T::deserialize_revisioned(reader)?))
51///   }
52/// }
53///
54/// impl<T> Revisioned for MyType<T>
55/// where
56///     T: Revisioned,
57/// {
58///     fn revision() -> u16 {
59///         1
60///     }
61/// }
62/// ```
63pub trait Revisioned {
64	/// Returns the current revision of this type.
65	fn revision() -> u16;
66	/// Returns the type id of this type.
67	#[inline]
68	fn type_id() -> std::any::TypeId
69	where
70		Self: 'static,
71	{
72		TypeId::of::<Self>()
73	}
74}
75
76pub trait SerializeRevisioned: Revisioned {
77	/// Serializes the struct using the specified `writer`.
78	fn serialize_revisioned<W: Write>(&self, w: &mut W) -> Result<(), Error>;
79}
80
81pub trait DeserializeRevisioned: Revisioned {
82	/// Deserializes a new instance of the struct from the specified `reader`.
83	fn deserialize_revisioned<R: Read>(r: &mut R) -> Result<Self, Error>
84	where
85		Self: Sized;
86}
87
88/// Deserialize a revisioned type from a reader
89#[inline]
90pub fn from_reader<R, T>(rdr: &mut R) -> Result<T, Error>
91where
92	R: Read,
93	T: DeserializeRevisioned,
94{
95	DeserializeRevisioned::deserialize_revisioned(rdr)
96}
97
98/// Deserialize a revisioned type from a slice of bytes
99#[inline]
100pub fn from_slice<T>(mut bytes: &[u8]) -> Result<T, Error>
101where
102	T: DeserializeRevisioned,
103{
104	DeserializeRevisioned::deserialize_revisioned(&mut bytes)
105}
106
107/// Serialize a revisioned type into a vec of bytes
108#[inline]
109pub fn to_writer<W, T>(writer: &mut W, t: &T) -> Result<(), Error>
110where
111	W: Write,
112	T: SerializeRevisioned,
113{
114	SerializeRevisioned::serialize_revisioned(t, writer)
115}
116
117/// Serialize a revisioned type into a vec of bytes
118#[inline]
119pub fn to_vec<T>(t: &T) -> Result<Vec<u8>, Error>
120where
121	T: SerializeRevisioned,
122{
123	let mut res = Vec::new();
124	SerializeRevisioned::serialize_revisioned(t, &mut res)?;
125	Ok(res)
126}