Skip to content

Commit

Permalink
feat(versionable): Add support for statically sized arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
nsarlin-zama committed Aug 2, 2024
1 parent 7e51285 commit 2342eff
Showing 1 changed file with 48 additions and 1 deletion.
49 changes: 48 additions & 1 deletion utils/tfhe-versionable/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ pub enum UnversionizeError {
from_type: String,
source: Box<dyn Error + Send + Sync>,
},

/// The length of a statically sized array is wrong
ArrayLength {
expected_size: usize,
found_size: usize,
},
}

impl Display for UnversionizeError {
Expand All @@ -97,6 +103,15 @@ impl Display for UnversionizeError {
Self::Conversion { from_type, source } => {
write!(f, "Failed to convert from {from_type}: {source}")
}
Self::ArrayLength {
expected_size,
found_size,
} => {
write!(
f,
"Expected array of size {expected_size}, found array of size {found_size}"
)
}
}
}
}
Expand All @@ -106,6 +121,7 @@ impl Error for UnversionizeError {
match self {
UnversionizeError::Upgrade { source, .. } => Some(source.as_ref()),
UnversionizeError::Conversion { source, .. } => Some(source.as_ref()),
UnversionizeError::ArrayLength { .. } => None,
}
}
}
Expand Down Expand Up @@ -262,7 +278,7 @@ impl<T: VersionizeVec + Clone> VersionizeOwned for Box<[T]> {
type VersionedOwned = T::VersionedVec;

fn versionize_owned(self) -> Self::VersionedOwned {
T::versionize_vec(self.iter().cloned().collect())
T::versionize_vec(self.to_vec())
}
}

Expand Down Expand Up @@ -312,6 +328,37 @@ impl<T: UnversionizeVec> Unversionize for Vec<T> {
}
}

// Since serde doesn't support arbitrary length arrays with const generics, the array
// is converted to a slice/vec.
impl<const N: usize, T: VersionizeSlice> Versionize for [T; N] {
type Versioned<'vers> = T::VersionedSlice<'vers> where T: 'vers;

fn versionize(&self) -> Self::Versioned<'_> {
T::versionize_slice(self)
}
}

impl<const N: usize, T: VersionizeVec + Clone> VersionizeOwned for [T; N] {
type VersionedOwned = T::VersionedVec;

fn versionize_owned(self) -> Self::VersionedOwned {
T::versionize_vec(self.to_vec())
}
}

impl<const N: usize, T: UnversionizeVec + Clone> Unversionize for [T; N] {
fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
let v = T::unversionize_vec(versioned)?;
let boxed_slice = v.into_boxed_slice();
TryInto::<Box<[T; N]>>::try_into(boxed_slice)
.map(|array| *array)
.map_err(|slice| UnversionizeError::ArrayLength {
expected_size: N,
found_size: slice.len(),
})
}
}

impl Versionize for String {
type Versioned<'vers> = &'vers str;

Expand Down

0 comments on commit 2342eff

Please sign in to comment.