tfhe_versionable/
lib.rs

1//! Provides a way to add versioning informations/backward compatibility on rust types used for
2//! serialization.
3//!
4//! This crates provides a set of traits [`Versionize`] and [`Unversionize`] that perform a
5//! conversion between a type and its `Versioned` counterpart. The versioned type is an enum
6//! that has a variant for each version of the type.
7//! These traits can be generated using the [`tfhe_versionable_derive::Versionize`] proc macro.
8
9pub mod deprecation;
10pub mod derived_traits;
11pub mod upgrade;
12
13use aligned_vec::{ABox, AVec};
14use deprecation::DeprecatedVersionError;
15use num_complex::Complex;
16use std::collections::{HashMap, HashSet};
17use std::convert::Infallible;
18use std::error::Error;
19use std::fmt::Display;
20use std::marker::PhantomData;
21use std::num::Wrapping;
22use std::sync::Arc;
23
24pub use derived_traits::{Version, VersionsDispatch};
25pub use upgrade::Upgrade;
26
27use serde::de::DeserializeOwned;
28use serde::Serialize;
29pub use tfhe_versionable_derive::{NotVersioned, Version, Versionize, VersionsDispatch};
30
31/// This trait means that the type can be converted into a versioned equivalent
32/// type.
33pub trait Versionize {
34    /// The equivalent versioned type. It should have a variant for each version.
35    /// It may own the underlying data or only hold a read-only reference to it.
36    type Versioned<'vers>: Serialize
37    where
38        Self: 'vers;
39
40    /// Wraps the object into a versioned enum with a variant for each version. This will
41    /// use references on the underlying types if possible.
42    fn versionize(&self) -> Self::Versioned<'_>;
43}
44
45pub trait VersionizeOwned {
46    type VersionedOwned: Serialize + DeserializeOwned;
47
48    /// Wraps the object into a versioned enum with a variant for each version. This will
49    /// clone the underlying types.
50    fn versionize_owned(self) -> Self::VersionedOwned;
51}
52
53/// This trait is used as a proxy to be more flexible when deriving Versionize for `Vec<T>`.
54///
55/// This way, we can chose to skip versioning `Vec<T>` if T is a native types but still versionize
56/// in a loop if T is a custom type.
57/// This is used as a workaround for feature(specialization) and to bypass the orphan rule.
58pub trait VersionizeSlice: Sized {
59    type VersionedSlice<'vers>: Serialize
60    where
61        Self: 'vers;
62
63    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_>;
64}
65
66pub trait VersionizeVec: Sized {
67    type VersionedVec: Serialize + DeserializeOwned;
68
69    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec;
70}
71
72#[derive(Debug)]
73/// Errors that can arise in the unversionizing process.
74pub enum UnversionizeError {
75    /// An error in the upgrade between `vers_from` and `vers_into`
76    Upgrade {
77        from_vers: String,
78        into_vers: String,
79        source: Box<dyn Error + Send + Sync>,
80    },
81
82    /// An error has been returned in the conversion method provided by the `try_from` parameter
83    /// attribute
84    Conversion {
85        from_type: String,
86        source: Box<dyn Error + Send + Sync>,
87    },
88
89    /// The length of a statically sized array is wrong
90    ArrayLength {
91        expected_size: usize,
92        found_size: usize,
93    },
94
95    /// A deprecated version has been found
96    DeprecatedVersion(DeprecatedVersionError),
97}
98
99impl Display for UnversionizeError {
100    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101        match self {
102            Self::Upgrade {
103                from_vers,
104                into_vers,
105                source,
106            } => write!(
107                f,
108                "Failed to upgrade from {from_vers} into {into_vers}: {source}"
109            ),
110            Self::Conversion { from_type, source } => {
111                write!(f, "Failed to convert from {from_type}: {source}")
112            }
113            Self::ArrayLength {
114                expected_size,
115                found_size,
116            } => {
117                write!(
118                    f,
119                    "Expected array of size {expected_size}, found array of size {found_size}"
120                )
121            }
122            Self::DeprecatedVersion(deprecation_error) => deprecation_error.fmt(f),
123        }
124    }
125}
126
127impl Error for UnversionizeError {
128    fn source(&self) -> Option<&(dyn Error + 'static)> {
129        match self {
130            UnversionizeError::Upgrade { source, .. } => Some(source.as_ref()),
131            UnversionizeError::Conversion { source, .. } => Some(source.as_ref()),
132            UnversionizeError::ArrayLength { .. } => None,
133            UnversionizeError::DeprecatedVersion(_) => None,
134        }
135    }
136}
137
138impl UnversionizeError {
139    pub fn upgrade<E: Error + 'static + Send + Sync>(
140        from_vers: &str,
141        into_vers: &str,
142        source: E,
143    ) -> Self {
144        Self::Upgrade {
145            from_vers: from_vers.to_string(),
146            into_vers: into_vers.to_string(),
147            source: Box::new(source),
148        }
149    }
150
151    pub fn conversion<E: Error + 'static + Send + Sync>(from_type: &str, source: E) -> Self {
152        Self::Conversion {
153            from_type: from_type.to_string(),
154            source: Box::new(source),
155        }
156    }
157}
158
159impl From<Infallible> for UnversionizeError {
160    fn from(_value: Infallible) -> Self {
161        panic!("Infallible error type should never be reached")
162    }
163}
164
165/// This trait means that we can convert from a versioned enum into the target type.
166///
167/// This trait can only be implemented on Owned/static types, whereas `Versionize` can also be
168/// implemented on reference types.
169pub trait Unversionize: VersionizeOwned + Sized {
170    /// Creates an object from a versioned enum, and eventually upgrades from previous
171    /// variants.
172    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError>;
173}
174
175pub trait UnversionizeVec: VersionizeVec {
176    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError>;
177}
178
179/// Marker trait for a type that it not really versioned, where the `versionize` method returns
180/// Self or &Self.
181pub trait NotVersioned: Versionize {}
182
183impl<T: NotVersioned + Serialize + DeserializeOwned + Clone> VersionizeSlice for T {
184    type VersionedSlice<'vers>
185        = &'vers [T]
186    where
187        T: 'vers;
188
189    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
190        slice
191    }
192}
193
194impl<T: NotVersioned + Serialize + DeserializeOwned + Clone> VersionizeVec for T {
195    type VersionedVec = Vec<T>;
196
197    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
198        vec
199    }
200}
201
202impl<T: NotVersioned + Serialize + DeserializeOwned + Clone> UnversionizeVec for T {
203    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
204        Ok(versioned)
205    }
206}
207
208/// implements the versionable traits for a rust primitive scalar type (integer, float, bool and
209/// char) Since these types won't move between versions, we consider that they are their own
210/// versionized types
211macro_rules! impl_scalar_versionize {
212    ($t:ty) => {
213        impl Versionize for $t {
214            type Versioned<'vers> = $t;
215
216            fn versionize(&self) -> Self::Versioned<'_> {
217                *self
218            }
219        }
220
221        impl VersionizeOwned for $t {
222            type VersionedOwned = $t;
223            fn versionize_owned(self) -> Self::VersionedOwned {
224                self
225            }
226        }
227
228        impl Unversionize for $t {
229            fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
230                Ok(versioned)
231            }
232        }
233
234        impl NotVersioned for $t {}
235    };
236}
237
238impl_scalar_versionize!(bool);
239
240impl_scalar_versionize!(u8);
241impl_scalar_versionize!(u16);
242impl_scalar_versionize!(u32);
243impl_scalar_versionize!(u64);
244impl_scalar_versionize!(u128);
245impl_scalar_versionize!(usize);
246
247impl_scalar_versionize!(i8);
248impl_scalar_versionize!(i16);
249impl_scalar_versionize!(i32);
250impl_scalar_versionize!(i64);
251impl_scalar_versionize!(i128);
252
253impl_scalar_versionize!(f32);
254impl_scalar_versionize!(f64);
255
256impl_scalar_versionize!(char);
257
258impl<T: Versionize> Versionize for Wrapping<T> {
259    type Versioned<'vers>
260        = Wrapping<T::Versioned<'vers>>
261    where
262        T: 'vers;
263
264    fn versionize(&self) -> Self::Versioned<'_> {
265        Wrapping(self.0.versionize())
266    }
267}
268
269impl<T: VersionizeOwned> VersionizeOwned for Wrapping<T> {
270    type VersionedOwned = Wrapping<T::VersionedOwned>;
271
272    fn versionize_owned(self) -> Self::VersionedOwned {
273        Wrapping(T::versionize_owned(self.0))
274    }
275}
276
277impl<T: Unversionize> Unversionize for Wrapping<T> {
278    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
279        Ok(Wrapping(T::unversionize(versioned.0)?))
280    }
281}
282
283impl<T: NotVersioned> NotVersioned for Wrapping<T> {}
284
285impl<T: Versionize> Versionize for Box<T> {
286    type Versioned<'vers>
287        = T::Versioned<'vers>
288    where
289        T: 'vers;
290
291    fn versionize(&self) -> Self::Versioned<'_> {
292        self.as_ref().versionize()
293    }
294}
295
296impl<T: VersionizeOwned> VersionizeOwned for Box<T> {
297    type VersionedOwned = Box<T::VersionedOwned>;
298
299    fn versionize_owned(self) -> Self::VersionedOwned {
300        Box::new(T::versionize_owned(*self))
301    }
302}
303
304impl<T: Unversionize> Unversionize for Box<T> {
305    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
306        Ok(Box::new(T::unversionize(*versioned)?))
307    }
308}
309
310impl<T: VersionizeSlice + Clone> Versionize for Box<[T]> {
311    type Versioned<'vers>
312        = T::VersionedSlice<'vers>
313    where
314        T: 'vers;
315
316    fn versionize(&self) -> Self::Versioned<'_> {
317        T::versionize_slice(self)
318    }
319}
320
321impl<T: VersionizeVec + Clone> VersionizeOwned for Box<[T]> {
322    type VersionedOwned = T::VersionedVec;
323
324    fn versionize_owned(self) -> Self::VersionedOwned {
325        T::versionize_vec(self.to_vec())
326    }
327}
328
329impl<T: UnversionizeVec + Clone> Unversionize for Box<[T]> {
330    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
331        T::unversionize_vec(versioned).map(|unver| unver.into_boxed_slice())
332    }
333}
334
335impl<T: VersionizeVec + Clone> VersionizeVec for Box<[T]> {
336    type VersionedVec = Vec<T::VersionedVec>;
337
338    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
339        vec.into_iter()
340            .map(|inner| inner.versionize_owned())
341            .collect()
342    }
343}
344
345impl<T: VersionizeSlice> VersionizeSlice for Box<[T]> {
346    type VersionedSlice<'vers>
347        = Vec<T::VersionedSlice<'vers>>
348    where
349        T: 'vers;
350
351    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
352        slice
353            .iter()
354            .map(|inner| T::versionize_slice(inner))
355            .collect()
356    }
357}
358
359impl<T: UnversionizeVec + Clone> UnversionizeVec for Box<[T]> {
360    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
361        versioned
362            .into_iter()
363            .map(Box::<[T]>::unversionize)
364            .collect()
365    }
366}
367
368impl<T: VersionizeSlice> Versionize for Vec<T> {
369    type Versioned<'vers>
370        = T::VersionedSlice<'vers>
371    where
372        T: 'vers;
373
374    fn versionize(&self) -> Self::Versioned<'_> {
375        T::versionize_slice(self)
376    }
377}
378
379impl<T: VersionizeVec> VersionizeOwned for Vec<T> {
380    type VersionedOwned = T::VersionedVec;
381
382    fn versionize_owned(self) -> Self::VersionedOwned {
383        T::versionize_vec(self)
384    }
385}
386
387impl<T: UnversionizeVec> Unversionize for Vec<T> {
388    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
389        T::unversionize_vec(versioned)
390    }
391}
392
393impl<T: VersionizeVec> VersionizeVec for Vec<T> {
394    type VersionedVec = Vec<T::VersionedVec>;
395
396    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
397        vec.into_iter()
398            .map(|inner| T::versionize_vec(inner))
399            .collect()
400    }
401}
402
403impl<T: VersionizeSlice> VersionizeSlice for Vec<T> {
404    type VersionedSlice<'vers>
405        = Vec<T::VersionedSlice<'vers>>
406    where
407        T: 'vers;
408
409    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
410        slice
411            .iter()
412            .map(|inner| T::versionize_slice(inner))
413            .collect()
414    }
415}
416
417impl<T: UnversionizeVec> UnversionizeVec for Vec<T> {
418    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
419        versioned
420            .into_iter()
421            .map(|inner| T::unversionize_vec(inner))
422            .collect()
423    }
424}
425
426impl<T: VersionizeSlice + Clone> Versionize for [T] {
427    type Versioned<'vers>
428        = T::VersionedSlice<'vers>
429    where
430        T: 'vers;
431
432    fn versionize(&self) -> Self::Versioned<'_> {
433        T::versionize_slice(self)
434    }
435}
436
437impl<T: VersionizeVec + Clone> VersionizeOwned for &[T] {
438    type VersionedOwned = T::VersionedVec;
439
440    fn versionize_owned(self) -> Self::VersionedOwned {
441        T::versionize_vec(self.to_vec())
442    }
443}
444
445impl<T: VersionizeVec + Clone> VersionizeVec for &[T] {
446    type VersionedVec = Vec<T::VersionedVec>;
447
448    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
449        vec.into_iter()
450            .map(|inner| T::versionize_vec(inner.to_vec()))
451            .collect()
452    }
453}
454
455impl<'a, T: VersionizeSlice> VersionizeSlice for &'a [T] {
456    type VersionedSlice<'vers>
457        = Vec<T::VersionedSlice<'vers>>
458    where
459        T: 'vers,
460        'a: 'vers;
461
462    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
463        slice
464            .iter()
465            .map(|inner| T::versionize_slice(inner))
466            .collect()
467    }
468}
469
470// Since serde doesn't support arbitrary length arrays with const generics, the array
471// is converted to a slice/vec.
472impl<const N: usize, T: VersionizeSlice> Versionize for [T; N] {
473    type Versioned<'vers>
474        = T::VersionedSlice<'vers>
475    where
476        T: 'vers;
477
478    fn versionize(&self) -> Self::Versioned<'_> {
479        T::versionize_slice(self)
480    }
481}
482
483impl<const N: usize, T: VersionizeVec + Clone> VersionizeOwned for [T; N] {
484    type VersionedOwned = T::VersionedVec;
485
486    fn versionize_owned(self) -> Self::VersionedOwned {
487        T::versionize_vec(self.to_vec())
488    }
489}
490
491impl<const N: usize, T: UnversionizeVec + Clone> Unversionize for [T; N] {
492    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
493        let v = T::unversionize_vec(versioned)?;
494        let boxed_slice = v.into_boxed_slice();
495        TryInto::<Box<[T; N]>>::try_into(boxed_slice)
496            .map(|array| *array)
497            .map_err(|slice| UnversionizeError::ArrayLength {
498                expected_size: N,
499                found_size: slice.len(),
500            })
501    }
502}
503
504impl<const N: usize, T: VersionizeVec + Clone> VersionizeVec for [T; N] {
505    type VersionedVec = Vec<T::VersionedVec>;
506
507    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
508        vec.into_iter()
509            .map(|inner| inner.versionize_owned())
510            .collect()
511    }
512}
513
514impl<const N: usize, T: VersionizeSlice> VersionizeSlice for [T; N] {
515    type VersionedSlice<'vers>
516        = Vec<T::VersionedSlice<'vers>>
517    where
518        T: 'vers;
519
520    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
521        slice
522            .iter()
523            .map(|inner| T::versionize_slice(inner))
524            .collect()
525    }
526}
527
528impl<const N: usize, T: UnversionizeVec + Clone> UnversionizeVec for [T; N] {
529    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
530        versioned.into_iter().map(<[T; N]>::unversionize).collect()
531    }
532}
533
534impl Versionize for String {
535    type Versioned<'vers> = &'vers str;
536
537    fn versionize(&self) -> Self::Versioned<'_> {
538        self.as_ref()
539    }
540}
541
542impl VersionizeOwned for String {
543    type VersionedOwned = Self;
544
545    fn versionize_owned(self) -> Self::VersionedOwned {
546        self
547    }
548}
549
550impl Unversionize for String {
551    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
552        Ok(versioned)
553    }
554}
555
556impl NotVersioned for String {}
557
558impl Versionize for str {
559    type Versioned<'vers> = &'vers str;
560
561    fn versionize(&self) -> Self::Versioned<'_> {
562        self
563    }
564}
565
566impl VersionizeOwned for &str {
567    type VersionedOwned = String;
568
569    fn versionize_owned(self) -> Self::VersionedOwned {
570        self.to_string()
571    }
572}
573
574impl NotVersioned for str {}
575
576impl<T: Versionize> Versionize for Option<T> {
577    type Versioned<'vers>
578        = Option<T::Versioned<'vers>>
579    where
580        T: 'vers;
581
582    fn versionize(&self) -> Self::Versioned<'_> {
583        self.as_ref().map(|val| val.versionize())
584    }
585}
586
587impl<T: VersionizeOwned> VersionizeOwned for Option<T> {
588    type VersionedOwned = Option<T::VersionedOwned>;
589
590    fn versionize_owned(self) -> Self::VersionedOwned {
591        self.map(|val| val.versionize_owned())
592    }
593}
594
595impl<T: Unversionize> Unversionize for Option<T> {
596    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
597        versioned.map(|val| T::unversionize(val)).transpose()
598    }
599}
600
601impl<T: NotVersioned> NotVersioned for Option<T> {}
602
603impl<T> Versionize for PhantomData<T> {
604    type Versioned<'vers>
605        = Self
606    where
607        Self: 'vers;
608
609    fn versionize(&self) -> Self::Versioned<'_> {
610        *self
611    }
612}
613
614impl<T> VersionizeOwned for PhantomData<T> {
615    type VersionedOwned = Self;
616
617    fn versionize_owned(self) -> Self::VersionedOwned {
618        self
619    }
620}
621
622impl<T> Unversionize for PhantomData<T> {
623    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
624        Ok(versioned)
625    }
626}
627
628impl<T> NotVersioned for PhantomData<T> {}
629
630impl<T: Versionize> Versionize for Arc<T> {
631    type Versioned<'vers>
632        = T::Versioned<'vers>
633    where
634        T: 'vers;
635
636    fn versionize(&self) -> Self::Versioned<'_> {
637        self.as_ref().versionize()
638    }
639}
640
641impl<T: VersionizeOwned + Clone> VersionizeOwned for Arc<T> {
642    type VersionedOwned = T::VersionedOwned;
643
644    fn versionize_owned(self) -> Self::VersionedOwned {
645        Arc::unwrap_or_clone(self).versionize_owned()
646    }
647}
648
649impl<T: Unversionize + Clone> Unversionize for Arc<T> {
650    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
651        Ok(Arc::new(T::unversionize(versioned)?))
652    }
653}
654
655impl<T: NotVersioned> NotVersioned for Arc<T> {}
656
657impl<T: Versionize> Versionize for Complex<T> {
658    type Versioned<'vers>
659        = Complex<T::Versioned<'vers>>
660    where
661        T: 'vers;
662
663    fn versionize(&self) -> Self::Versioned<'_> {
664        Complex {
665            re: self.re.versionize(),
666            im: self.im.versionize(),
667        }
668    }
669}
670
671impl<T: VersionizeOwned> VersionizeOwned for Complex<T> {
672    type VersionedOwned = Complex<T::VersionedOwned>;
673
674    fn versionize_owned(self) -> Self::VersionedOwned {
675        Complex {
676            re: self.re.versionize_owned(),
677            im: self.im.versionize_owned(),
678        }
679    }
680}
681
682impl<T: Unversionize> Unversionize for Complex<T> {
683    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
684        Ok(Complex {
685            re: T::unversionize(versioned.re)?,
686            im: T::unversionize(versioned.im)?,
687        })
688    }
689}
690
691impl<T: NotVersioned> NotVersioned for Complex<T> {}
692
693impl<T: Versionize> Versionize for ABox<T> {
694    type Versioned<'vers>
695        = T::Versioned<'vers>
696    where
697        T: 'vers;
698
699    fn versionize(&self) -> Self::Versioned<'_> {
700        self.as_ref().versionize()
701    }
702}
703
704impl<T: VersionizeOwned + Clone> VersionizeOwned for ABox<T> {
705    // Alignment doesn't matter for versioned types
706    type VersionedOwned = Box<T::VersionedOwned>;
707
708    fn versionize_owned(self) -> Self::VersionedOwned {
709        Box::new(T::versionize_owned(T::clone(&self)))
710    }
711}
712
713impl<T: Unversionize + Clone> Unversionize for ABox<T>
714where
715    T::VersionedOwned: Clone,
716{
717    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
718        Ok(ABox::new(0, T::unversionize((*versioned).to_owned())?))
719    }
720}
721
722impl<T: VersionizeSlice + Clone> Versionize for ABox<[T]> {
723    type Versioned<'vers>
724        = T::VersionedSlice<'vers>
725    where
726        T: 'vers;
727
728    fn versionize(&self) -> Self::Versioned<'_> {
729        T::versionize_slice(self)
730    }
731}
732
733impl<T: VersionizeVec + Clone> VersionizeOwned for ABox<[T]> {
734    type VersionedOwned = T::VersionedVec;
735
736    fn versionize_owned(self) -> Self::VersionedOwned {
737        T::versionize_vec(self.iter().cloned().collect())
738    }
739}
740
741impl<T: UnversionizeVec + Clone> Unversionize for ABox<[T]> {
742    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
743        T::unversionize_vec(versioned).map(|unver| AVec::from_iter(0, unver).into_boxed_slice())
744    }
745}
746
747impl<T: NotVersioned + Clone + Serialize + DeserializeOwned> NotVersioned for ABox<[T]> {}
748
749impl<T: VersionizeSlice> Versionize for AVec<T> {
750    type Versioned<'vers>
751        = T::VersionedSlice<'vers>
752    where
753        T: 'vers;
754
755    fn versionize(&self) -> Self::Versioned<'_> {
756        T::versionize_slice(self)
757    }
758}
759
760// Alignment doesn't matter for versioned types
761impl<T: VersionizeVec + Clone> VersionizeOwned for AVec<T> {
762    type VersionedOwned = T::VersionedVec;
763
764    fn versionize_owned(self) -> Self::VersionedOwned {
765        T::versionize_vec(self.to_vec())
766    }
767}
768
769impl<T: UnversionizeVec + Clone> Unversionize for AVec<T> {
770    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
771        T::unversionize_vec(versioned).map(|unver| AVec::from_iter(0, unver))
772    }
773}
774
775impl<T: NotVersioned + Clone + Serialize + DeserializeOwned> NotVersioned for AVec<T> {}
776
777impl Versionize for () {
778    type Versioned<'vers> = ();
779
780    fn versionize(&self) -> Self::Versioned<'_> {}
781}
782
783impl VersionizeOwned for () {
784    type VersionedOwned = ();
785
786    fn versionize_owned(self) -> Self::VersionedOwned {}
787}
788
789impl Unversionize for () {
790    fn unversionize(_versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
791        Ok(())
792    }
793}
794
795impl NotVersioned for () {}
796
797// TODO: use a macro for more tuple sizes
798impl<T: Versionize, U: Versionize> Versionize for (T, U) {
799    type Versioned<'vers>
800        = (T::Versioned<'vers>, U::Versioned<'vers>)
801    where
802        T: 'vers,
803        U: 'vers;
804
805    fn versionize(&self) -> Self::Versioned<'_> {
806        (self.0.versionize(), self.1.versionize())
807    }
808}
809
810impl<T: VersionizeOwned, U: VersionizeOwned> VersionizeOwned for (T, U) {
811    type VersionedOwned = (T::VersionedOwned, U::VersionedOwned);
812
813    fn versionize_owned(self) -> Self::VersionedOwned {
814        (self.0.versionize_owned(), self.1.versionize_owned())
815    }
816}
817
818impl<T: Unversionize, U: Unversionize> Unversionize for (T, U) {
819    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
820        Ok((T::unversionize(versioned.0)?, U::unversionize(versioned.1)?))
821    }
822}
823
824impl<T: Versionize, U: Versionize> VersionizeSlice for (T, U) {
825    type VersionedSlice<'vers>
826        = Vec<(T::Versioned<'vers>, U::Versioned<'vers>)>
827    where
828        T: 'vers,
829        U: 'vers;
830
831    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
832        slice
833            .iter()
834            .map(|(t, u)| (t.versionize(), u.versionize()))
835            .collect()
836    }
837}
838
839impl<T: VersionizeOwned, U: VersionizeOwned> VersionizeVec for (T, U) {
840    type VersionedVec = Vec<(T::VersionedOwned, U::VersionedOwned)>;
841
842    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
843        vec.into_iter()
844            .map(|(t, u)| (t.versionize_owned(), u.versionize_owned()))
845            .collect()
846    }
847}
848
849impl<T: Unversionize, U: Unversionize> UnversionizeVec for (T, U) {
850    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
851        versioned
852            .into_iter()
853            .map(|(t, u)| Ok((T::unversionize(t)?, U::unversionize(u)?)))
854            .collect()
855    }
856}
857
858impl<T: Versionize, U: Versionize, V: Versionize> Versionize for (T, U, V) {
859    type Versioned<'vers>
860        = (
861        T::Versioned<'vers>,
862        U::Versioned<'vers>,
863        V::Versioned<'vers>,
864    )
865    where
866        T: 'vers,
867        U: 'vers,
868        V: 'vers;
869
870    fn versionize(&self) -> Self::Versioned<'_> {
871        (
872            self.0.versionize(),
873            self.1.versionize(),
874            self.2.versionize(),
875        )
876    }
877}
878
879impl<T: VersionizeOwned, U: VersionizeOwned, V: VersionizeOwned> VersionizeOwned for (T, U, V) {
880    type VersionedOwned = (T::VersionedOwned, U::VersionedOwned, V::VersionedOwned);
881
882    fn versionize_owned(self) -> Self::VersionedOwned {
883        (
884            self.0.versionize_owned(),
885            self.1.versionize_owned(),
886            self.2.versionize_owned(),
887        )
888    }
889}
890
891impl<T: Unversionize, U: Unversionize, V: Unversionize> Unversionize for (T, U, V) {
892    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
893        Ok((
894            T::unversionize(versioned.0)?,
895            U::unversionize(versioned.1)?,
896            V::unversionize(versioned.2)?,
897        ))
898    }
899}
900
901impl<T: Versionize, U: Versionize, V: Versionize> VersionizeSlice for (T, U, V) {
902    type VersionedSlice<'vers>
903        = Vec<(
904        T::Versioned<'vers>,
905        U::Versioned<'vers>,
906        V::Versioned<'vers>,
907    )>
908    where
909        T: 'vers,
910        U: 'vers,
911        V: 'vers;
912
913    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
914        slice
915            .iter()
916            .map(|(t, u, v)| (t.versionize(), u.versionize(), v.versionize()))
917            .collect()
918    }
919}
920
921impl<T: VersionizeOwned, U: VersionizeOwned, V: VersionizeOwned> VersionizeVec for (T, U, V) {
922    type VersionedVec = Vec<(T::VersionedOwned, U::VersionedOwned, V::VersionedOwned)>;
923
924    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
925        vec.into_iter()
926            .map(|(t, u, v)| {
927                (
928                    t.versionize_owned(),
929                    u.versionize_owned(),
930                    v.versionize_owned(),
931                )
932            })
933            .collect()
934    }
935}
936
937impl<T: Unversionize, U: Unversionize, V: Unversionize> UnversionizeVec for (T, U, V) {
938    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
939        versioned
940            .into_iter()
941            .map(|(t, u, v)| {
942                Ok((
943                    T::unversionize(t)?,
944                    U::unversionize(u)?,
945                    V::unversionize(v)?,
946                ))
947            })
948            .collect()
949    }
950}
951
952// converts to `Vec<T::Versioned>` for the versioned type, so we don't have to derive
953// Eq/Hash on it.
954impl<T: Versionize> Versionize for HashSet<T> {
955    type Versioned<'vers>
956        = Vec<T::Versioned<'vers>>
957    where
958        T: 'vers;
959
960    fn versionize(&self) -> Self::Versioned<'_> {
961        self.iter().map(|val| val.versionize()).collect()
962    }
963}
964
965impl<T: VersionizeOwned> VersionizeOwned for HashSet<T> {
966    type VersionedOwned = Vec<T::VersionedOwned>;
967
968    fn versionize_owned(self) -> Self::VersionedOwned {
969        self.into_iter().map(|val| val.versionize_owned()).collect()
970    }
971}
972
973impl<T: Unversionize + std::hash::Hash + Eq> Unversionize for HashSet<T> {
974    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
975        versioned
976            .into_iter()
977            .map(|val| T::unversionize(val))
978            .collect()
979    }
980}
981
982// converts to `Vec<(K::Versioned, V::Versioned)>` for the versioned type, so we don't have to
983// derive Eq/Hash on it.
984impl<K: Versionize, V: Versionize> Versionize for HashMap<K, V> {
985    type Versioned<'vers>
986        = Vec<(K::Versioned<'vers>, V::Versioned<'vers>)>
987    where
988        K: 'vers,
989        V: 'vers;
990
991    fn versionize(&self) -> Self::Versioned<'_> {
992        self.iter()
993            .map(|(key, val)| (key.versionize(), val.versionize()))
994            .collect()
995    }
996}
997
998impl<K: VersionizeOwned, V: VersionizeOwned> VersionizeOwned for HashMap<K, V> {
999    type VersionedOwned = Vec<(K::VersionedOwned, V::VersionedOwned)>;
1000
1001    fn versionize_owned(self) -> Self::VersionedOwned {
1002        self.into_iter()
1003            .map(|(key, val)| (key.versionize_owned(), val.versionize_owned()))
1004            .collect()
1005    }
1006}
1007
1008impl<K: Unversionize + std::hash::Hash + Eq, V: Unversionize> Unversionize for HashMap<K, V> {
1009    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
1010        versioned
1011            .into_iter()
1012            .map(|(key, val)| Ok((K::unversionize(key)?, V::unversionize(val)?)))
1013            .collect()
1014    }
1015}