Skip to main content

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