-
Notifications
You must be signed in to change notification settings - Fork 151
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Mostly test in the main that the derived code actually works
- Loading branch information
1 parent
4d1a7de
commit 68821b1
Showing
6 changed files
with
245 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/// In this example, we use a generic that is not versionable itself. Only its associated types | ||
/// should be versioned. | ||
use tfhe_versionable::{Versionize, VersionsDispatch}; | ||
|
||
trait WithAssociated { | ||
type Assoc; | ||
type OtherAssoc; | ||
} | ||
|
||
struct Marker; | ||
|
||
impl WithAssociated for Marker { | ||
type Assoc = u64; | ||
|
||
type OtherAssoc = u32; | ||
} | ||
|
||
#[derive(VersionsDispatch)] | ||
#[allow(unused)] | ||
enum MyStructVersions<T: WithAssociated> { | ||
V0(MyStruct<T>), | ||
} | ||
|
||
#[derive(Versionize)] | ||
#[versionize(MyStructVersions)] | ||
struct MyStruct<T: WithAssociated> { | ||
val: T::Assoc, | ||
other_val: T::OtherAssoc, | ||
} | ||
|
||
fn main() { | ||
let ms = MyStruct::<Marker> { | ||
val: 27, | ||
other_val: 54, | ||
}; | ||
|
||
ms.versionize(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,74 @@ | ||
//! This example shows how to use the `bound` attribute to add a specific bound that is needed to be | ||
//! able to derive `Versionize` | ||
//! Example of a simple struct with an Upgrade impl that requires a specific bound. | ||
//! In that case, the previous versions of the type used a string as a representation, but it has | ||
//! been changed to a Generic. For the upgrade to work, we need to be able to create this generic | ||
//! from a String. | ||
use serde::de::DeserializeOwned; | ||
use serde::Serialize; | ||
use tfhe_versionable::{ | ||
Unversionize, UnversionizeError, Versionize, VersionizeOwned, VersionsDispatch, | ||
}; | ||
use std::error::Error; | ||
use std::io::Cursor; | ||
use std::str::FromStr; | ||
|
||
// Example of a simple struct with a manual Versionize impl that requires a specific bound | ||
struct MyStruct<T> { | ||
val: T, | ||
} | ||
use tfhe_versionable::{Unversionize, Upgrade, Version, Versionize, VersionsDispatch}; | ||
|
||
impl<T: Serialize + DeserializeOwned> Versionize for MyStruct<T> { | ||
type Versioned<'vers> = &'vers T where T: 'vers; | ||
/// The previous version of our application | ||
mod v0 { | ||
use tfhe_versionable::{Versionize, VersionsDispatch}; | ||
|
||
fn versionize(&self) -> Self::Versioned<'_> { | ||
&self.val | ||
#[derive(Versionize)] | ||
#[versionize(MyStructVersions)] | ||
pub(super) struct MyStruct { | ||
pub(super) val: String, | ||
} | ||
} | ||
|
||
impl<T: Serialize + DeserializeOwned + ToOwned<Owned = T>> VersionizeOwned for MyStruct<T> { | ||
type VersionedOwned = T; | ||
|
||
fn versionize_owned(self) -> Self::VersionedOwned { | ||
self.val.to_owned() | ||
#[derive(VersionsDispatch)] | ||
#[allow(unused)] | ||
pub(super) enum MyStructVersions { | ||
V0(MyStruct), | ||
} | ||
} | ||
|
||
impl<T: Serialize + DeserializeOwned + ToOwned<Owned = T>> Unversionize for MyStruct<T> { | ||
fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> { | ||
Ok(MyStruct { val: versioned }) | ||
} | ||
#[derive(Version)] | ||
struct MyStructV0 { | ||
val: String, | ||
} | ||
|
||
// The additional bound can be specified on the parent struct using this attribute. This is similar | ||
// to what serde does. You can also use #[versionize(OuterVersions, bound(unversionize = "T: | ||
// ToOwned<Owned = T>"))] if the bound is only needed for the Unversionize impl. | ||
#[derive(Versionize)] | ||
#[versionize(OuterVersions, bound = "T: ToOwned<Owned = T>")] | ||
struct Outer<T> { | ||
inner: MyStruct<T>, | ||
#[versionize(MyStructVersions)] | ||
struct MyStruct<T> { | ||
val: T, | ||
} | ||
|
||
impl<T: FromStr> Upgrade<MyStruct<T>> for MyStructV0 | ||
where | ||
<T as FromStr>::Err: Error + Send + Sync + 'static, | ||
{ | ||
type Error = <T as FromStr>::Err; | ||
|
||
fn upgrade(self) -> Result<MyStruct<T>, Self::Error> { | ||
let val = T::from_str(&self.val)?; | ||
|
||
Ok(MyStruct { val }) | ||
} | ||
} | ||
|
||
#[derive(VersionsDispatch)] | ||
#[allow(unused)] | ||
enum OuterVersions<T: ToOwned<Owned = T>> { | ||
V0(Outer<T>), | ||
enum MyStructVersions<T> { | ||
V0(MyStructV0), | ||
V1(MyStruct<T>), | ||
} | ||
|
||
fn main() {} | ||
fn main() { | ||
let val = 64; | ||
let stru_v0 = v0::MyStruct { | ||
val: format!("{val}"), | ||
}; | ||
|
||
let mut ser = Vec::new(); | ||
ciborium::ser::into_writer(&stru_v0.versionize(), &mut ser).unwrap(); | ||
|
||
let unvers = | ||
MyStruct::<u64>::unversionize(ciborium::de::from_reader(&mut Cursor::new(&ser)).unwrap()) | ||
.unwrap(); | ||
|
||
assert_eq!(unvers.val, val); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters