fix(versionable): compatibility between "convert" and generics

This commit is contained in:
Nicolas Sarlin
2024-10-02 15:30:11 +02:00
committed by Nicolas Sarlin
parent 2af4676588
commit 2b14b22820
8 changed files with 646 additions and 206 deletions

View File

@@ -3,48 +3,57 @@
use tfhe_versionable::{Unversionize, Versionize, VersionsDispatch};
#[derive(Clone, Versionize)]
#[versionize(SerializableMyStructVersions, from = SerializableMyStruct, into = SerializableMyStruct)]
struct MyStruct {
// To mimic serde parameters, this can also be expressed as
// "#[versionize(from = SerializableMyStruct, into = SerializableMyStruct)]"
#[versionize(convert = "SerializableMyStruct<T>")]
struct MyStruct<T> {
val: u64,
generics: T,
}
#[derive(Versionize)]
#[versionize(SerializableMyStructVersions)]
struct SerializableMyStruct {
struct SerializableMyStruct<T> {
high: u32,
low: u32,
generics: T,
}
#[derive(VersionsDispatch)]
#[allow(unused)]
enum SerializableMyStructVersions {
V0(SerializableMyStruct),
enum SerializableMyStructVersions<T> {
V0(SerializableMyStruct<T>),
}
impl From<MyStruct> for SerializableMyStruct {
fn from(value: MyStruct) -> Self {
println!("{}", value.val);
impl<T> From<MyStruct<T>> for SerializableMyStruct<T> {
fn from(value: MyStruct<T>) -> Self {
Self {
high: (value.val >> 32) as u32,
low: (value.val & 0xffffffff) as u32,
generics: value.generics,
}
}
}
impl From<SerializableMyStruct> for MyStruct {
fn from(value: SerializableMyStruct) -> Self {
impl<T> From<SerializableMyStruct<T>> for MyStruct<T> {
fn from(value: SerializableMyStruct<T>) -> Self {
Self {
val: ((value.high as u64) << 32) | (value.low as u64),
generics: value.generics,
}
}
}
fn main() {
let stru = MyStruct { val: 37 };
let stru = MyStruct {
val: 37,
generics: 90,
};
let serialized = bincode::serialize(&stru.versionize()).unwrap();
let stru_decoded = MyStruct::unversionize(bincode::deserialize(&serialized).unwrap()).unwrap();
let stru_decoded: MyStruct<i32> =
MyStruct::unversionize(bincode::deserialize(&serialized).unwrap()).unwrap();
assert_eq!(stru.val, stru_decoded.val)
}

View File

@@ -0,0 +1,51 @@
//! Checks compatibility between the "convert" feature and bounds on the From/Into trait
use tfhe_versionable::{Unversionize, Versionize, VersionsDispatch};
#[derive(Clone, Versionize)]
#[versionize(try_convert = "SerializableMyStruct")]
struct MyStruct<T> {
generics: T,
}
#[derive(Versionize)]
#[versionize(SerializableMyStructVersions)]
struct SerializableMyStruct {
concrete: u64,
}
#[derive(VersionsDispatch)]
#[allow(unused)]
enum SerializableMyStructVersions {
V0(SerializableMyStruct),
}
impl<T: Into<u64>> From<MyStruct<T>> for SerializableMyStruct {
fn from(value: MyStruct<T>) -> Self {
Self {
concrete: value.generics.into(),
}
}
}
impl<T: TryFrom<u64>> TryFrom<SerializableMyStruct> for MyStruct<T> {
fn try_from(value: SerializableMyStruct) -> Result<Self, Self::Error> {
Ok(Self {
generics: value.concrete.try_into()?,
})
}
type Error = T::Error;
}
#[test]
fn test() {
let stru = MyStruct { generics: 90u32 };
let serialized = bincode::serialize(&stru.versionize()).unwrap();
let stru_decoded: MyStruct<u32> =
MyStruct::unversionize(bincode::deserialize(&serialized).unwrap()).unwrap();
assert_eq!(stru.generics, stru_decoded.generics)
}

View File

@@ -0,0 +1,58 @@
//! Checks compatibility between the "convert" feature and generics
use tfhe_versionable::{Unversionize, Versionize, VersionsDispatch};
#[derive(Clone, Versionize)]
#[versionize(convert = "SerializableMyStruct<T>")]
struct MyStruct<T> {
val: u64,
generics: T,
}
#[derive(Versionize)]
#[versionize(SerializableMyStructVersions)]
struct SerializableMyStruct<T> {
high: u32,
low: u32,
generics: T,
}
#[derive(VersionsDispatch)]
#[allow(unused)]
enum SerializableMyStructVersions<T> {
V0(SerializableMyStruct<T>),
}
impl<T> From<MyStruct<T>> for SerializableMyStruct<T> {
fn from(value: MyStruct<T>) -> Self {
Self {
high: (value.val >> 32) as u32,
low: (value.val & 0xffffffff) as u32,
generics: value.generics,
}
}
}
impl<T> From<SerializableMyStruct<T>> for MyStruct<T> {
fn from(value: SerializableMyStruct<T>) -> Self {
Self {
val: ((value.high as u64) << 32) | (value.low as u64),
generics: value.generics,
}
}
}
#[test]
fn test() {
let stru = MyStruct {
val: 37,
generics: 90,
};
let serialized = bincode::serialize(&stru.versionize()).unwrap();
let stru_decoded: MyStruct<i32> =
MyStruct::unversionize(bincode::deserialize(&serialized).unwrap()).unwrap();
assert_eq!(stru.val, stru_decoded.val)
}