mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-09 14:47:56 -05:00
chore(versionable)!: Impl std::error::Error for UnversionizeError
BREAKING CHANGE: The `Upgrade` trait now requires to specify the Error type as an associated type (similar to `TryFrom`)
This commit is contained in:
committed by
Nicolas Sarlin
parent
4d934f512a
commit
c8ddc0f008
@@ -336,7 +336,7 @@ impl DispatchType {
|
||||
value
|
||||
.upgrade()
|
||||
.map_err(|e|
|
||||
#error_ty::upgrade(#src_variant, #dest_variant, &e)
|
||||
#error_ty::upgrade(#src_variant, #dest_variant, e)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ impl VersionizeAttribute {
|
||||
} else if let Some(target) = &self.try_from {
|
||||
let target_name = format!("{}", target.to_token_stream());
|
||||
quote! { #target::unversionize(#arg_name).and_then(|value| TryInto::<Self>::try_into(value)
|
||||
.map_err(|e| #error::conversion(#target_name, &format!("{}", e))))
|
||||
.map_err(|e| #error::conversion(#target_name, e)))
|
||||
}
|
||||
} else {
|
||||
quote! { #arg_name.try_into() }
|
||||
|
||||
@@ -37,6 +37,9 @@ mod v1 {
|
||||
pub struct MyStruct(pub u32);
|
||||
|
||||
mod backward_compat {
|
||||
use std::error::Error;
|
||||
use std::fmt::Display;
|
||||
|
||||
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};
|
||||
|
||||
use super::MyStruct;
|
||||
@@ -44,11 +47,23 @@ mod v1 {
|
||||
#[derive(Version)]
|
||||
pub struct MyStructV0(pub Option<u32>);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EmptyValueError;
|
||||
|
||||
impl Display for EmptyValueError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Value is empty")
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for EmptyValueError {}
|
||||
|
||||
impl Upgrade<MyStruct> for MyStructV0 {
|
||||
fn upgrade(self) -> Result<MyStruct, String> {
|
||||
type Error = EmptyValueError;
|
||||
fn upgrade(self) -> Result<MyStruct, Self::Error> {
|
||||
match self.0 {
|
||||
Some(val) => Ok(MyStruct(val)),
|
||||
None => Err("Cannot convert from empty \"MyStructV0\"".to_string()),
|
||||
None => Err(EmptyValueError),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
//! The simple example, with manual implementation of the versionize trait
|
||||
|
||||
use std::convert::Infallible;
|
||||
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tfhe_versionable::{Unversionize, UnversionizeError, Upgrade, Versionize, VersionizeOwned};
|
||||
@@ -15,7 +17,9 @@ struct MyStructV0 {
|
||||
}
|
||||
|
||||
impl<T: Default> Upgrade<MyStruct<T>> for MyStructV0 {
|
||||
fn upgrade(self) -> Result<MyStruct<T>, String> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<MyStruct<T>, Self::Error> {
|
||||
Ok(MyStruct {
|
||||
attr: T::default(),
|
||||
builtin: self.builtin,
|
||||
@@ -68,7 +72,7 @@ impl<T: Default + VersionizeOwned + Unversionize + Serialize + DeserializeOwned>
|
||||
match versioned {
|
||||
MyStructVersionsDispatchOwned::V0(v0) => v0
|
||||
.upgrade()
|
||||
.map_err(|e| UnversionizeError::upgrade("V0", "V1", &e)),
|
||||
.map_err(|e| UnversionizeError::upgrade("V0", "V1", e)),
|
||||
MyStructVersionsDispatchOwned::V1(v1) => Ok(Self {
|
||||
attr: T::unversionize(v1.attr)?,
|
||||
builtin: v1.builtin,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
//! An example of recursive versioning
|
||||
|
||||
use std::convert::Infallible;
|
||||
|
||||
use tfhe_versionable::{Upgrade, Version, Versionize, VersionsDispatch};
|
||||
|
||||
#[derive(Versionize)]
|
||||
@@ -15,7 +17,9 @@ struct MyStructInnerV0 {
|
||||
}
|
||||
|
||||
impl<T: Default> Upgrade<MyStructInner<T>> for MyStructInnerV0 {
|
||||
fn upgrade(self) -> Result<MyStructInner<T>, String> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<MyStructInner<T>, Self::Error> {
|
||||
Ok(MyStructInner {
|
||||
attr: T::default(),
|
||||
builtin: 0,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
//! Shows a basic usage of this crate
|
||||
|
||||
use std::convert::Infallible;
|
||||
|
||||
use tfhe_versionable::{Unversionize, Upgrade, Version, Versionize, VersionsDispatch};
|
||||
|
||||
// The structure that should be versioned, as defined in your code
|
||||
@@ -21,7 +23,9 @@ struct MyStructV0 {
|
||||
// The Upgrade trait tells how to go from the first version to the last. During unversioning, the
|
||||
// upgrade method will be called on the deserialized value enough times to go to the last variant.
|
||||
impl<T: Default> Upgrade<MyStruct<T>> for MyStructV0 {
|
||||
fn upgrade(self) -> Result<MyStruct<T>, String> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<MyStruct<T>, Self::Error> {
|
||||
Ok(MyStruct {
|
||||
attr: T::default(),
|
||||
builtin: self.builtin,
|
||||
|
||||
@@ -37,6 +37,8 @@ mod v1 {
|
||||
pub struct MyStruct<T: Default>(pub u32, pub T);
|
||||
|
||||
mod backward_compat {
|
||||
use std::convert::Infallible;
|
||||
|
||||
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};
|
||||
|
||||
use super::MyStruct;
|
||||
@@ -45,7 +47,9 @@ mod v1 {
|
||||
pub struct MyStructV0(pub u32);
|
||||
|
||||
impl<T: Default> Upgrade<MyStruct<T>> for MyStructV0 {
|
||||
fn upgrade(self) -> Result<MyStruct<T>, String> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<MyStruct<T>, Self::Error> {
|
||||
Ok(MyStruct(self.0, T::default()))
|
||||
}
|
||||
}
|
||||
@@ -81,6 +85,8 @@ mod v2 {
|
||||
}
|
||||
|
||||
mod backward_compat {
|
||||
use std::convert::Infallible;
|
||||
|
||||
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};
|
||||
|
||||
use super::{MyEnum, MyStruct};
|
||||
@@ -89,7 +95,9 @@ mod v2 {
|
||||
pub struct MyStructV0(pub u32);
|
||||
|
||||
impl<T: Default> Upgrade<MyStructV1<T>> for MyStructV0 {
|
||||
fn upgrade(self) -> Result<MyStructV1<T>, String> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<MyStructV1<T>, Self::Error> {
|
||||
Ok(MyStructV1(self.0, T::default()))
|
||||
}
|
||||
}
|
||||
@@ -98,7 +106,9 @@ mod v2 {
|
||||
pub struct MyStructV1<T>(pub u32, pub T);
|
||||
|
||||
impl<T: Default> Upgrade<MyStruct<T>> for MyStructV1<T> {
|
||||
fn upgrade(self) -> Result<MyStruct<T>, String> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<MyStruct<T>, Self::Error> {
|
||||
Ok(MyStruct {
|
||||
count: self.0,
|
||||
attr: T::default(),
|
||||
|
||||
@@ -12,6 +12,7 @@ pub mod upgrade;
|
||||
use aligned_vec::{ABox, AVec};
|
||||
use num_complex::Complex;
|
||||
use std::convert::Infallible;
|
||||
use std::error::Error;
|
||||
use std::fmt::Display;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
@@ -70,12 +71,15 @@ pub enum UnversionizeError {
|
||||
Upgrade {
|
||||
from_vers: String,
|
||||
into_vers: String,
|
||||
message: String,
|
||||
source: Box<dyn Error>,
|
||||
},
|
||||
|
||||
/// An error has been returned in the conversion method provided by the `try_from` parameter
|
||||
/// attribute
|
||||
Conversion { from_type: String, message: String },
|
||||
Conversion {
|
||||
from_type: String,
|
||||
source: Box<dyn Error>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Display for UnversionizeError {
|
||||
@@ -84,31 +88,40 @@ impl Display for UnversionizeError {
|
||||
Self::Upgrade {
|
||||
from_vers,
|
||||
into_vers,
|
||||
message,
|
||||
source,
|
||||
} => write!(
|
||||
f,
|
||||
"Failed to upgrade from {from_vers} into {into_vers}: {message}"
|
||||
"Failed to upgrade from {from_vers} into {into_vers}: {source}"
|
||||
),
|
||||
Self::Conversion { from_type, message } => {
|
||||
write!(f, "Failed to convert from {from_type}: {message}")
|
||||
Self::Conversion { from_type, source } => {
|
||||
write!(f, "Failed to convert from {from_type}: {source}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for UnversionizeError {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
match self {
|
||||
UnversionizeError::Upgrade { source, .. } => Some(source.as_ref()),
|
||||
UnversionizeError::Conversion { source, .. } => Some(source.as_ref()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UnversionizeError {
|
||||
pub fn upgrade(from_vers: &str, into_vers: &str, message: &str) -> Self {
|
||||
pub fn upgrade<E: Error + 'static>(from_vers: &str, into_vers: &str, source: E) -> Self {
|
||||
Self::Upgrade {
|
||||
from_vers: from_vers.to_string(),
|
||||
into_vers: into_vers.to_string(),
|
||||
message: message.to_string(),
|
||||
source: Box::new(source),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn conversion(from_type: &str, message: &str) -> Self {
|
||||
pub fn conversion<E: Error + 'static>(from_type: &str, source: E) -> Self {
|
||||
Self::Conversion {
|
||||
from_type: from_type.to_string(),
|
||||
message: message.to_string(),
|
||||
source: Box::new(source),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
/// This trait should be implemented for each version of the original type that is not the current
|
||||
/// one. The upgrade method is called in chains until we get to the last version of the type.
|
||||
pub trait Upgrade<T> {
|
||||
fn upgrade(self) -> Result<T, String>;
|
||||
type Error: std::error::Error;
|
||||
fn upgrade(self) -> Result<T, Self::Error>;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ mod v1 {
|
||||
pub struct MyStruct<T: Default>(pub u32, pub T);
|
||||
|
||||
mod backward_compat {
|
||||
use std::convert::Infallible;
|
||||
|
||||
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};
|
||||
|
||||
use super::MyStruct;
|
||||
@@ -57,7 +59,9 @@ mod v1 {
|
||||
pub struct MyStructV0(pub u32);
|
||||
|
||||
impl<T: Default> Upgrade<MyStruct<T>> for MyStructV0 {
|
||||
fn upgrade(self) -> Result<MyStruct<T>, String> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<MyStruct<T>, Self::Error> {
|
||||
Ok(MyStruct(self.0, T::default()))
|
||||
}
|
||||
}
|
||||
@@ -85,6 +89,8 @@ mod v2 {
|
||||
}
|
||||
|
||||
mod backward_compat {
|
||||
use std::convert::Infallible;
|
||||
|
||||
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};
|
||||
|
||||
use super::MyStruct;
|
||||
@@ -93,7 +99,9 @@ mod v2 {
|
||||
pub struct MyStructV0(pub u32);
|
||||
|
||||
impl<T: Default> Upgrade<MyStructV1<T>> for MyStructV0 {
|
||||
fn upgrade(self) -> Result<MyStructV1<T>, String> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<MyStructV1<T>, Self::Error> {
|
||||
Ok(MyStructV1(self.0, T::default()))
|
||||
}
|
||||
}
|
||||
@@ -102,7 +110,9 @@ mod v2 {
|
||||
pub struct MyStructV1<T>(pub u32, pub T);
|
||||
|
||||
impl<T: Default> Upgrade<MyStruct<T>> for MyStructV1<T> {
|
||||
fn upgrade(self) -> Result<MyStruct<T>, String> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn upgrade(self) -> Result<MyStruct<T>, Self::Error> {
|
||||
Ok(MyStruct {
|
||||
count: self.0,
|
||||
attr: T::default(),
|
||||
|
||||
Reference in New Issue
Block a user