Skip to content

Commit b7b3884

Browse files
committed
feat(versionable): Add support for statically sized arrays
1 parent 781f78c commit b7b3884

File tree

1 file changed

+48
-1
lines changed
  • utils/tfhe-versionable/src

1 file changed

+48
-1
lines changed

utils/tfhe-versionable/src/lib.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ pub enum UnversionizeError {
8181
from_type: String,
8282
source: Box<dyn Error + Send + Sync>,
8383
},
84+
85+
/// The length of a statically sized array is wrong
86+
ArrayLength {
87+
expected_size: usize,
88+
found_size: usize,
89+
},
8490
}
8591

8692
impl Display for UnversionizeError {
@@ -97,6 +103,15 @@ impl Display for UnversionizeError {
97103
Self::Conversion { from_type, source } => {
98104
write!(f, "Failed to convert from {from_type}: {source}")
99105
}
106+
Self::ArrayLength {
107+
expected_size,
108+
found_size,
109+
} => {
110+
write!(
111+
f,
112+
"Expected array of size {expected_size}, found array of size {found_size}"
113+
)
114+
}
100115
}
101116
}
102117
}
@@ -106,6 +121,7 @@ impl Error for UnversionizeError {
106121
match self {
107122
UnversionizeError::Upgrade { source, .. } => Some(source.as_ref()),
108123
UnversionizeError::Conversion { source, .. } => Some(source.as_ref()),
124+
UnversionizeError::ArrayLength { .. } => None,
109125
}
110126
}
111127
}
@@ -262,7 +278,7 @@ impl<T: VersionizeVec + Clone> VersionizeOwned for Box<[T]> {
262278
type VersionedOwned = T::VersionedVec;
263279

264280
fn versionize_owned(self) -> Self::VersionedOwned {
265-
T::versionize_vec(self.iter().cloned().collect())
281+
T::versionize_vec(self.to_vec())
266282
}
267283
}
268284

@@ -312,6 +328,37 @@ impl<T: UnversionizeVec> Unversionize for Vec<T> {
312328
}
313329
}
314330

331+
// Since serde doesn't support arbitrary length arrays with const generics, the array
332+
// is converted to a slice/vec.
333+
impl<const N: usize, T: VersionizeSlice> Versionize for [T; N] {
334+
type Versioned<'vers> = T::VersionedSlice<'vers> where T: 'vers;
335+
336+
fn versionize(&self) -> Self::Versioned<'_> {
337+
T::versionize_slice(self)
338+
}
339+
}
340+
341+
impl<const N: usize, T: VersionizeVec + Clone> VersionizeOwned for [T; N] {
342+
type VersionedOwned = T::VersionedVec;
343+
344+
fn versionize_owned(self) -> Self::VersionedOwned {
345+
T::versionize_vec(self.to_vec())
346+
}
347+
}
348+
349+
impl<const N: usize, T: UnversionizeVec + Clone> Unversionize for [T; N] {
350+
fn unversionize(versioned: Self::VersionedOwned) -> Result<Self, UnversionizeError> {
351+
let v = T::unversionize_vec(versioned)?;
352+
let boxed_slice = v.into_boxed_slice();
353+
TryInto::<Box<[T; N]>>::try_into(boxed_slice)
354+
.map(|array| *array)
355+
.map_err(|slice| UnversionizeError::ArrayLength {
356+
expected_size: N,
357+
found_size: slice.len(),
358+
})
359+
}
360+
}
361+
315362
impl Versionize for String {
316363
type Versioned<'vers> = &'vers str;
317364

0 commit comments

Comments
 (0)