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<T: Versionize> Versionize for Wrapping<T> {
275    type Versioned<'vers>
276        = Wrapping<T::Versioned<'vers>>
277    where
278        T: 'vers;
279
280    fn versionize(&self) -> Self::Versioned<'_> {
281        Wrapping(self.0.versionize())
282    }
283}
284
285impl<T: VersionizeOwned> VersionizeOwned for Wrapping<T> {
286    type VersionedOwned = Wrapping<T::VersionedOwned>;
287
288    fn versionize_owned(self) -> Self::VersionedOwned {
289        Wrapping(T::versionize_owned(self.0))
290    }
291}
292
293impl<T: Unversionize> Unversionize for Wrapping<T> {
294    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
295        Ok(Wrapping(T::unversionize(versioned.0)?))
296    }
297}
298
299impl<T: NotVersioned> NotVersioned for Wrapping<T> {}
300
301impl<T: Versionize> Versionize for Box<T> {
302    type Versioned<'vers>
303        = T::Versioned<'vers>
304    where
305        T: 'vers;
306
307    fn versionize(&self) -> Self::Versioned<'_> {
308        self.as_ref().versionize()
309    }
310}
311
312impl<T: VersionizeOwned> VersionizeOwned for Box<T> {
313    type VersionedOwned = Box<T::VersionedOwned>;
314
315    fn versionize_owned(self) -> Self::VersionedOwned {
316        Box::new(T::versionize_owned(*self))
317    }
318}
319
320impl<T: Unversionize> Unversionize for Box<T> {
321    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
322        Ok(Box::new(T::unversionize(*versioned)?))
323    }
324}
325
326impl<T: VersionizeSlice + Clone> Versionize for Box<[T]> {
327    type Versioned<'vers>
328        = T::VersionedSlice<'vers>
329    where
330        T: 'vers;
331
332    fn versionize(&self) -> Self::Versioned<'_> {
333        T::versionize_slice(self)
334    }
335}
336
337impl<T: VersionizeVec + Clone> VersionizeOwned for Box<[T]> {
338    type VersionedOwned = T::VersionedVec;
339
340    fn versionize_owned(self) -> Self::VersionedOwned {
341        T::versionize_vec(self.to_vec())
342    }
343}
344
345impl<T: UnversionizeVec + Clone> Unversionize for Box<[T]> {
346    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
347        T::unversionize_vec(versioned).map(|unver| unver.into_boxed_slice())
348    }
349}
350
351impl<T: VersionizeVec + Clone> VersionizeVec for Box<[T]> {
352    type VersionedVec = Vec<T::VersionedVec>;
353
354    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
355        vec.into_iter()
356            .map(|inner| inner.versionize_owned())
357            .collect()
358    }
359}
360
361impl<T: VersionizeSlice> VersionizeSlice for Box<[T]> {
362    type VersionedSlice<'vers>
363        = Vec<T::VersionedSlice<'vers>>
364    where
365        T: 'vers;
366
367    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
368        slice
369            .iter()
370            .map(|inner| T::versionize_slice(inner))
371            .collect()
372    }
373}
374
375impl<T: UnversionizeVec + Clone> UnversionizeVec for Box<[T]> {
376    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
377        versioned
378            .into_iter()
379            .map(Box::<[T]>::unversionize)
380            .collect()
381    }
382}
383
384impl<T: VersionizeSlice> Versionize for Vec<T> {
385    type Versioned<'vers>
386        = T::VersionedSlice<'vers>
387    where
388        T: 'vers;
389
390    fn versionize(&self) -> Self::Versioned<'_> {
391        T::versionize_slice(self)
392    }
393}
394
395impl<T: VersionizeVec> VersionizeOwned for Vec<T> {
396    type VersionedOwned = T::VersionedVec;
397
398    fn versionize_owned(self) -> Self::VersionedOwned {
399        T::versionize_vec(self)
400    }
401}
402
403impl<T: UnversionizeVec> Unversionize for Vec<T> {
404    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
405        T::unversionize_vec(versioned)
406    }
407}
408
409impl<T: VersionizeVec> VersionizeVec for Vec<T> {
410    type VersionedVec = Vec<T::VersionedVec>;
411
412    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
413        vec.into_iter()
414            .map(|inner| T::versionize_vec(inner))
415            .collect()
416    }
417}
418
419impl<T: VersionizeSlice> VersionizeSlice for Vec<T> {
420    type VersionedSlice<'vers>
421        = Vec<T::VersionedSlice<'vers>>
422    where
423        T: 'vers;
424
425    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
426        slice
427            .iter()
428            .map(|inner| T::versionize_slice(inner))
429            .collect()
430    }
431}
432
433impl<T: UnversionizeVec> UnversionizeVec for Vec<T> {
434    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
435        versioned
436            .into_iter()
437            .map(|inner| T::unversionize_vec(inner))
438            .collect()
439    }
440}
441
442impl<T: VersionizeSlice + Clone> Versionize for [T] {
443    type Versioned<'vers>
444        = T::VersionedSlice<'vers>
445    where
446        T: 'vers;
447
448    fn versionize(&self) -> Self::Versioned<'_> {
449        T::versionize_slice(self)
450    }
451}
452
453impl<T: VersionizeVec + Clone> VersionizeOwned for &[T] {
454    type VersionedOwned = T::VersionedVec;
455
456    fn versionize_owned(self) -> Self::VersionedOwned {
457        T::versionize_vec(self.to_vec())
458    }
459}
460
461impl<T: VersionizeVec + Clone> VersionizeVec for &[T] {
462    type VersionedVec = Vec<T::VersionedVec>;
463
464    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
465        vec.into_iter()
466            .map(|inner| T::versionize_vec(inner.to_vec()))
467            .collect()
468    }
469}
470
471impl<'a, T: VersionizeSlice> VersionizeSlice for &'a [T] {
472    type VersionedSlice<'vers>
473        = Vec<T::VersionedSlice<'vers>>
474    where
475        T: 'vers,
476        'a: 'vers;
477
478    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
479        slice
480            .iter()
481            .map(|inner| T::versionize_slice(inner))
482            .collect()
483    }
484}
485
486// Since serde doesn't support arbitrary length arrays with const generics, the array
487// is converted to a slice/vec.
488impl<const N: usize, T: VersionizeSlice> Versionize for [T; N] {
489    type Versioned<'vers>
490        = T::VersionedSlice<'vers>
491    where
492        T: 'vers;
493
494    fn versionize(&self) -> Self::Versioned<'_> {
495        T::versionize_slice(self)
496    }
497}
498
499impl<const N: usize, T: VersionizeVec + Clone> VersionizeOwned for [T; N] {
500    type VersionedOwned = T::VersionedVec;
501
502    fn versionize_owned(self) -> Self::VersionedOwned {
503        T::versionize_vec(self.to_vec())
504    }
505}
506
507impl<const N: usize, T: UnversionizeVec + Clone> Unversionize for [T; N] {
508    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
509        let v = T::unversionize_vec(versioned)?;
510        let boxed_slice = v.into_boxed_slice();
511        TryInto::<Box<[T; N]>>::try_into(boxed_slice)
512            .map(|array| *array)
513            .map_err(|slice| UnversionizeError::ArrayLength {
514                expected_size: N,
515                found_size: slice.len(),
516            })
517    }
518}
519
520impl<const N: usize, T: VersionizeVec + Clone> VersionizeVec for [T; N] {
521    type VersionedVec = Vec<T::VersionedVec>;
522
523    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
524        vec.into_iter()
525            .map(|inner| inner.versionize_owned())
526            .collect()
527    }
528}
529
530impl<const N: usize, T: VersionizeSlice> VersionizeSlice for [T; N] {
531    type VersionedSlice<'vers>
532        = Vec<T::VersionedSlice<'vers>>
533    where
534        T: 'vers;
535
536    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
537        slice
538            .iter()
539            .map(|inner| T::versionize_slice(inner))
540            .collect()
541    }
542}
543
544impl<const N: usize, T: UnversionizeVec + Clone> UnversionizeVec for [T; N] {
545    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
546        versioned.into_iter().map(<[T; N]>::unversionize).collect()
547    }
548}
549
550impl Versionize for String {
551    type Versioned<'vers> = &'vers str;
552
553    fn versionize(&self) -> Self::Versioned<'_> {
554        self.as_ref()
555    }
556}
557
558impl VersionizeOwned for String {
559    type VersionedOwned = Self;
560
561    fn versionize_owned(self) -> Self::VersionedOwned {
562        self
563    }
564}
565
566impl Unversionize for String {
567    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
568        Ok(versioned)
569    }
570}
571
572impl NotVersioned for String {}
573
574impl Versionize for str {
575    type Versioned<'vers> = &'vers str;
576
577    fn versionize(&self) -> Self::Versioned<'_> {
578        self
579    }
580}
581
582impl VersionizeOwned for &str {
583    type VersionedOwned = String;
584
585    fn versionize_owned(self) -> Self::VersionedOwned {
586        self.to_string()
587    }
588}
589
590impl NotVersioned for str {}
591
592impl<T: Versionize> Versionize for Option<T> {
593    type Versioned<'vers>
594        = Option<T::Versioned<'vers>>
595    where
596        T: 'vers;
597
598    fn versionize(&self) -> Self::Versioned<'_> {
599        self.as_ref().map(|val| val.versionize())
600    }
601}
602
603impl<T: VersionizeOwned> VersionizeOwned for Option<T> {
604    type VersionedOwned = Option<T::VersionedOwned>;
605
606    fn versionize_owned(self) -> Self::VersionedOwned {
607        self.map(|val| val.versionize_owned())
608    }
609}
610
611impl<T: Unversionize> Unversionize for Option<T> {
612    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
613        versioned.map(|val| T::unversionize(val)).transpose()
614    }
615}
616
617impl<T: NotVersioned> NotVersioned for Option<T> {}
618
619impl<T> Versionize for PhantomData<T> {
620    type Versioned<'vers>
621        = Self
622    where
623        Self: 'vers;
624
625    fn versionize(&self) -> Self::Versioned<'_> {
626        *self
627    }
628}
629
630impl<T> VersionizeOwned for PhantomData<T> {
631    type VersionedOwned = Self;
632
633    fn versionize_owned(self) -> Self::VersionedOwned {
634        self
635    }
636}
637
638impl<T> Unversionize for PhantomData<T> {
639    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
640        Ok(versioned)
641    }
642}
643
644impl<T> NotVersioned for PhantomData<T> {}
645
646impl<T: Versionize> Versionize for Arc<T> {
647    type Versioned<'vers>
648        = T::Versioned<'vers>
649    where
650        T: 'vers;
651
652    fn versionize(&self) -> Self::Versioned<'_> {
653        self.as_ref().versionize()
654    }
655}
656
657impl<T: VersionizeOwned + Clone> VersionizeOwned for Arc<T> {
658    type VersionedOwned = T::VersionedOwned;
659
660    fn versionize_owned(self) -> Self::VersionedOwned {
661        Arc::unwrap_or_clone(self).versionize_owned()
662    }
663}
664
665impl<T: Unversionize + Clone> Unversionize for Arc<T> {
666    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
667        Ok(Arc::new(T::unversionize(versioned)?))
668    }
669}
670
671impl<T: NotVersioned> NotVersioned for Arc<T> {}
672
673impl<T: Versionize> Versionize for Complex<T> {
674    type Versioned<'vers>
675        = Complex<T::Versioned<'vers>>
676    where
677        T: 'vers;
678
679    fn versionize(&self) -> Self::Versioned<'_> {
680        Complex {
681            re: self.re.versionize(),
682            im: self.im.versionize(),
683        }
684    }
685}
686
687impl<T: VersionizeOwned> VersionizeOwned for Complex<T> {
688    type VersionedOwned = Complex<T::VersionedOwned>;
689
690    fn versionize_owned(self) -> Self::VersionedOwned {
691        Complex {
692            re: self.re.versionize_owned(),
693            im: self.im.versionize_owned(),
694        }
695    }
696}
697
698impl<T: Unversionize> Unversionize for Complex<T> {
699    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
700        Ok(Complex {
701            re: T::unversionize(versioned.re)?,
702            im: T::unversionize(versioned.im)?,
703        })
704    }
705}
706
707impl<T: NotVersioned> NotVersioned for Complex<T> {}
708
709impl<T: Versionize> Versionize for ABox<T> {
710    type Versioned<'vers>
711        = T::Versioned<'vers>
712    where
713        T: 'vers;
714
715    fn versionize(&self) -> Self::Versioned<'_> {
716        self.as_ref().versionize()
717    }
718}
719
720impl<T: VersionizeOwned + Clone> VersionizeOwned for ABox<T> {
721    // Alignment doesn't matter for versioned types
722    type VersionedOwned = Box<T::VersionedOwned>;
723
724    fn versionize_owned(self) -> Self::VersionedOwned {
725        Box::new(T::versionize_owned(T::clone(&self)))
726    }
727}
728
729impl<T: Unversionize + Clone> Unversionize for ABox<T>
730where
731    T::VersionedOwned: Clone,
732{
733    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
734        Ok(ABox::new(0, T::unversionize((*versioned).to_owned())?))
735    }
736}
737
738impl<T: VersionizeSlice + Clone> Versionize for ABox<[T]> {
739    type Versioned<'vers>
740        = T::VersionedSlice<'vers>
741    where
742        T: 'vers;
743
744    fn versionize(&self) -> Self::Versioned<'_> {
745        T::versionize_slice(self)
746    }
747}
748
749impl<T: VersionizeVec + Clone> VersionizeOwned for ABox<[T]> {
750    type VersionedOwned = T::VersionedVec;
751
752    fn versionize_owned(self) -> Self::VersionedOwned {
753        T::versionize_vec(self.iter().cloned().collect())
754    }
755}
756
757impl<T: UnversionizeVec + Clone> Unversionize for ABox<[T]> {
758    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
759        T::unversionize_vec(versioned).map(|unver| AVec::from_iter(0, unver).into_boxed_slice())
760    }
761}
762
763impl<T: NotVersioned + Clone + Serialize + DeserializeOwned> NotVersioned for ABox<[T]> {}
764
765impl<T: VersionizeSlice> Versionize for AVec<T> {
766    type Versioned<'vers>
767        = T::VersionedSlice<'vers>
768    where
769        T: 'vers;
770
771    fn versionize(&self) -> Self::Versioned<'_> {
772        T::versionize_slice(self)
773    }
774}
775
776// Alignment doesn't matter for versioned types
777impl<T: VersionizeVec + Clone> VersionizeOwned for AVec<T> {
778    type VersionedOwned = T::VersionedVec;
779
780    fn versionize_owned(self) -> Self::VersionedOwned {
781        T::versionize_vec(self.to_vec())
782    }
783}
784
785impl<T: UnversionizeVec + Clone> Unversionize for AVec<T> {
786    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
787        T::unversionize_vec(versioned).map(|unver| AVec::from_iter(0, unver))
788    }
789}
790
791impl<T: NotVersioned + Clone + Serialize + DeserializeOwned> NotVersioned for AVec<T> {}
792
793impl Versionize for () {
794    type Versioned<'vers> = ();
795
796    fn versionize(&self) -> Self::Versioned<'_> {}
797}
798
799impl VersionizeOwned for () {
800    type VersionedOwned = ();
801
802    fn versionize_owned(self) -> Self::VersionedOwned {}
803}
804
805impl Unversionize for () {
806    fn unversionize(_versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
807        Ok(())
808    }
809}
810
811impl NotVersioned for () {}
812
813// TODO: use a macro for more tuple sizes
814impl<T: Versionize, U: Versionize> Versionize for (T, U) {
815    type Versioned<'vers>
816        = (T::Versioned<'vers>, U::Versioned<'vers>)
817    where
818        T: 'vers,
819        U: 'vers;
820
821    fn versionize(&self) -> Self::Versioned<'_> {
822        (self.0.versionize(), self.1.versionize())
823    }
824}
825
826impl<T: VersionizeOwned, U: VersionizeOwned> VersionizeOwned for (T, U) {
827    type VersionedOwned = (T::VersionedOwned, U::VersionedOwned);
828
829    fn versionize_owned(self) -> Self::VersionedOwned {
830        (self.0.versionize_owned(), self.1.versionize_owned())
831    }
832}
833
834impl<T: Unversionize, U: Unversionize> Unversionize for (T, U) {
835    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
836        Ok((T::unversionize(versioned.0)?, U::unversionize(versioned.1)?))
837    }
838}
839
840impl<T: Versionize, U: Versionize> VersionizeSlice for (T, U) {
841    type VersionedSlice<'vers>
842        = Vec<(T::Versioned<'vers>, U::Versioned<'vers>)>
843    where
844        T: 'vers,
845        U: 'vers;
846
847    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
848        slice
849            .iter()
850            .map(|(t, u)| (t.versionize(), u.versionize()))
851            .collect()
852    }
853}
854
855impl<T: VersionizeOwned, U: VersionizeOwned> VersionizeVec for (T, U) {
856    type VersionedVec = Vec<(T::VersionedOwned, U::VersionedOwned)>;
857
858    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
859        vec.into_iter()
860            .map(|(t, u)| (t.versionize_owned(), u.versionize_owned()))
861            .collect()
862    }
863}
864
865impl<T: Unversionize, U: Unversionize> UnversionizeVec for (T, U) {
866    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
867        versioned
868            .into_iter()
869            .map(|(t, u)| Ok((T::unversionize(t)?, U::unversionize(u)?)))
870            .collect()
871    }
872}
873
874impl<T: Versionize, U: Versionize, V: Versionize> Versionize for (T, U, V) {
875    type Versioned<'vers>
876        = (
877        T::Versioned<'vers>,
878        U::Versioned<'vers>,
879        V::Versioned<'vers>,
880    )
881    where
882        T: 'vers,
883        U: 'vers,
884        V: 'vers;
885
886    fn versionize(&self) -> Self::Versioned<'_> {
887        (
888            self.0.versionize(),
889            self.1.versionize(),
890            self.2.versionize(),
891        )
892    }
893}
894
895impl<T: VersionizeOwned, U: VersionizeOwned, V: VersionizeOwned> VersionizeOwned for (T, U, V) {
896    type VersionedOwned = (T::VersionedOwned, U::VersionedOwned, V::VersionedOwned);
897
898    fn versionize_owned(self) -> Self::VersionedOwned {
899        (
900            self.0.versionize_owned(),
901            self.1.versionize_owned(),
902            self.2.versionize_owned(),
903        )
904    }
905}
906
907impl<T: Unversionize, U: Unversionize, V: Unversionize> Unversionize for (T, U, V) {
908    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
909        Ok((
910            T::unversionize(versioned.0)?,
911            U::unversionize(versioned.1)?,
912            V::unversionize(versioned.2)?,
913        ))
914    }
915}
916
917impl<T: Versionize, U: Versionize, V: Versionize> VersionizeSlice for (T, U, V) {
918    type VersionedSlice<'vers>
919        = Vec<(
920        T::Versioned<'vers>,
921        U::Versioned<'vers>,
922        V::Versioned<'vers>,
923    )>
924    where
925        T: 'vers,
926        U: 'vers,
927        V: 'vers;
928
929    fn versionize_slice(slice: &[Self]) -> Self::VersionedSlice<'_> {
930        slice
931            .iter()
932            .map(|(t, u, v)| (t.versionize(), u.versionize(), v.versionize()))
933            .collect()
934    }
935}
936
937impl<T: VersionizeOwned, U: VersionizeOwned, V: VersionizeOwned> VersionizeVec for (T, U, V) {
938    type VersionedVec = Vec<(T::VersionedOwned, U::VersionedOwned, V::VersionedOwned)>;
939
940    fn versionize_vec(vec: Vec<Self>) -> Self::VersionedVec {
941        vec.into_iter()
942            .map(|(t, u, v)| {
943                (
944                    t.versionize_owned(),
945                    u.versionize_owned(),
946                    v.versionize_owned(),
947                )
948            })
949            .collect()
950    }
951}
952
953impl<T: Unversionize, U: Unversionize, V: Unversionize> UnversionizeVec for (T, U, V) {
954    fn unversionize_vec(versioned: Self::VersionedVec) -> Result<Vec<Self>, UnversionizeError> {
955        versioned
956            .into_iter()
957            .map(|(t, u, v)| {
958                Ok((
959                    T::unversionize(t)?,
960                    U::unversionize(u)?,
961                    V::unversionize(v)?,
962                ))
963            })
964            .collect()
965    }
966}
967
968// converts to `Vec<T::Versioned>` for the versioned type, so we don't have to derive
969// Eq/Hash on it.
970impl<T: Versionize> Versionize for HashSet<T> {
971    type Versioned<'vers>
972        = Vec<T::Versioned<'vers>>
973    where
974        T: 'vers;
975
976    fn versionize(&self) -> Self::Versioned<'_> {
977        self.iter().map(|val| val.versionize()).collect()
978    }
979}
980
981impl<T: VersionizeOwned> VersionizeOwned for HashSet<T> {
982    type VersionedOwned = Vec<T::VersionedOwned>;
983
984    fn versionize_owned(self) -> Self::VersionedOwned {
985        self.into_iter().map(|val| val.versionize_owned()).collect()
986    }
987}
988
989impl<T: Unversionize + std::hash::Hash + Eq> Unversionize for HashSet<T> {
990    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
991        versioned
992            .into_iter()
993            .map(|val| T::unversionize(val))
994            .collect()
995    }
996}
997
998impl<T: Versionize> Versionize for BTreeSet<T> {
999    type Versioned<'vers>
1000        = Vec<T::Versioned<'vers>>
1001    where
1002        T: 'vers;
1003
1004    fn versionize(&self) -> Self::Versioned<'_> {
1005        self.iter().map(|val| val.versionize()).collect()
1006    }
1007}
1008
1009impl<T: VersionizeOwned> VersionizeOwned for BTreeSet<T> {
1010    type VersionedOwned = Vec<T::VersionedOwned>;
1011
1012    fn versionize_owned(self) -> Self::VersionedOwned {
1013        self.into_iter().map(|val| val.versionize_owned()).collect()
1014    }
1015}
1016
1017impl<T: Unversionize + Ord> Unversionize for BTreeSet<T> {
1018    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
1019        versioned
1020            .into_iter()
1021            .map(|val| T::unversionize(val))
1022            .collect()
1023    }
1024}
1025
1026// converts to `Vec<(K::Versioned, V::Versioned)>` for the versioned type, so we don't have to
1027// derive Eq/Hash on it.
1028impl<K: Versionize, V: Versionize> Versionize for HashMap<K, V> {
1029    type Versioned<'vers>
1030        = Vec<(K::Versioned<'vers>, V::Versioned<'vers>)>
1031    where
1032        K: 'vers,
1033        V: 'vers;
1034
1035    fn versionize(&self) -> Self::Versioned<'_> {
1036        self.iter()
1037            .map(|(key, val)| (key.versionize(), val.versionize()))
1038            .collect()
1039    }
1040}
1041
1042impl<K: VersionizeOwned, V: VersionizeOwned> VersionizeOwned for HashMap<K, V> {
1043    type VersionedOwned = Vec<(K::VersionedOwned, V::VersionedOwned)>;
1044
1045    fn versionize_owned(self) -> Self::VersionedOwned {
1046        self.into_iter()
1047            .map(|(key, val)| (key.versionize_owned(), val.versionize_owned()))
1048            .collect()
1049    }
1050}
1051
1052impl<K: Unversionize + std::hash::Hash + Eq, V: Unversionize> Unversionize for HashMap<K, V> {
1053    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
1054        versioned
1055            .into_iter()
1056            .map(|(key, val)| Ok((K::unversionize(key)?, V::unversionize(val)?)))
1057            .collect()
1058    }
1059}
1060
1061impl<K: Versionize, V: Versionize> Versionize for BTreeMap<K, V> {
1062    type Versioned<'vers>
1063        = Vec<(K::Versioned<'vers>, V::Versioned<'vers>)>
1064    where
1065        K: 'vers,
1066        V: 'vers;
1067
1068    fn versionize(&self) -> Self::Versioned<'_> {
1069        self.iter()
1070            .map(|(key, val)| (key.versionize(), val.versionize()))
1071            .collect()
1072    }
1073}
1074
1075impl<K: VersionizeOwned, V: VersionizeOwned> VersionizeOwned for BTreeMap<K, V> {
1076    type VersionedOwned = Vec<(K::VersionedOwned, V::VersionedOwned)>;
1077
1078    fn versionize_owned(self) -> Self::VersionedOwned {
1079        self.into_iter()
1080            .map(|(key, val)| (key.versionize_owned(), val.versionize_owned()))
1081            .collect()
1082    }
1083}
1084
1085impl<K: Unversionize + Ord, V: Unversionize> Unversionize for BTreeMap<K, V> {
1086    fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
1087        versioned
1088            .into_iter()
1089            .map(|(key, val)| Ok((K::unversionize(key)?, V::unversionize(val)?)))
1090            .collect()
1091    }
1092}