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;
14pub mod specialised;
15
16pub use crate::error::Error;
17pub use derive::revisioned;
18
19use std::any::TypeId;
20use std::io::{Read, Write};
21
22pub mod prelude {
23	pub use crate::{revisioned, DeserializeRevisioned, Revisioned, SerializeRevisioned};
24}
25
26/// Trait that provides an interface for version aware serialization and deserialization.
27///
28/// Example implementation
29/// ```
30/// use revision::Error;
31/// use revision::prelude::*;
32///
33/// struct MyType<T>(T);
34///
35/// impl<T> SerializeRevisioned for MyType<T>
36/// where
37///    T: SerializeRevisioned,
38/// {
39///    #[inline]
40///   fn serialize_revisioned<W: std::io::Write>(&self, writer: &mut W) -> Result<(), Error> {
41///       self.0.serialize_revisioned(writer)
42///   }
43/// }
44///
45/// impl<T> DeserializeRevisioned for MyType<T>
46/// where
47///    T: DeserializeRevisioned,
48/// {
49///   #[inline]
50///   fn deserialize_revisioned<R: std::io::Read>(reader: &mut R) -> Result<Self, Error> {
51///       Ok(MyType(T::deserialize_revisioned(reader)?))
52///   }
53/// }
54///
55/// impl<T> Revisioned for MyType<T>
56/// where
57///     T: Revisioned,
58/// {
59///     fn revision() -> u16 {
60///         1
61///     }
62/// }
63/// ```
64pub trait Revisioned {
65	/// Returns the current revision of this type.
66	fn revision() -> u16;
67	/// Returns the type id of this type.
68	#[inline]
69	fn type_id() -> std::any::TypeId
70	where
71		Self: 'static,
72	{
73		TypeId::of::<Self>()
74	}
75}
76
77pub trait SerializeRevisioned: Revisioned {
78	/// Serializes the struct using the specficifed `writer`.
79	fn serialize_revisioned<W: Write>(&self, w: &mut W) -> Result<(), Error>;
80}
81
82pub trait DeserializeRevisioned: Revisioned {
83	/// Deserializes a new instance of the struct from the specficifed `reader`.
84	fn deserialize_revisioned<R: Read>(r: &mut R) -> Result<Self, Error>
85	where
86		Self: Sized;
87}
88
89/// Deserialize a revisioned type from a reader
90#[inline]
91pub fn from_reader<R, T>(rdr: &mut R) -> Result<T, Error>
92where
93	R: Read,
94	T: DeserializeRevisioned,
95{
96	DeserializeRevisioned::deserialize_revisioned(rdr)
97}
98
99/// Deserialize a revisioned type from a slice of bytes
100#[inline]
101pub fn from_slice<T>(mut bytes: &[u8]) -> Result<T, Error>
102where
103	T: DeserializeRevisioned,
104{
105	DeserializeRevisioned::deserialize_revisioned(&mut bytes)
106}
107
108/// Serialize a revisioned type into a vec of bytes
109#[inline]
110pub fn to_writer<W, T>(writer: &mut W, t: &T) -> Result<(), Error>
111where
112	W: Write,
113	T: SerializeRevisioned,
114{
115	SerializeRevisioned::serialize_revisioned(t, writer)
116}
117
118/// Serialize a revisioned type into a vec of bytes
119#[inline]
120pub fn to_vec<T>(t: &T) -> Result<Vec<u8>, Error>
121where
122	T: SerializeRevisioned,
123{
124	let mut res = Vec::new();
125	SerializeRevisioned::serialize_revisioned(t, &mut res)?;
126	Ok(res)
127}