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