@@ -81,6 +81,12 @@ pub enum UnversionizeError {
81
81
from_type : String ,
82
82
source : Box < dyn Error + Send + Sync > ,
83
83
} ,
84
+
85
+ /// The length of a statically sized array is wrong
86
+ ArrayLength {
87
+ expected_size : usize ,
88
+ found_size : usize ,
89
+ } ,
84
90
}
85
91
86
92
impl Display for UnversionizeError {
@@ -97,6 +103,15 @@ impl Display for UnversionizeError {
97
103
Self :: Conversion { from_type, source } => {
98
104
write ! ( f, "Failed to convert from {from_type}: {source}" )
99
105
}
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
+ }
100
115
}
101
116
}
102
117
}
@@ -106,6 +121,7 @@ impl Error for UnversionizeError {
106
121
match self {
107
122
UnversionizeError :: Upgrade { source, .. } => Some ( source. as_ref ( ) ) ,
108
123
UnversionizeError :: Conversion { source, .. } => Some ( source. as_ref ( ) ) ,
124
+ UnversionizeError :: ArrayLength { .. } => None ,
109
125
}
110
126
}
111
127
}
@@ -262,7 +278,7 @@ impl<T: VersionizeVec + Clone> VersionizeOwned for Box<[T]> {
262
278
type VersionedOwned = T :: VersionedVec ;
263
279
264
280
fn versionize_owned ( self ) -> Self :: VersionedOwned {
265
- T :: versionize_vec ( self . iter ( ) . cloned ( ) . collect ( ) )
281
+ T :: versionize_vec ( self . to_vec ( ) )
266
282
}
267
283
}
268
284
@@ -312,6 +328,37 @@ impl<T: UnversionizeVec> Unversionize for Vec<T> {
312
328
}
313
329
}
314
330
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
+
315
362
impl Versionize for String {
316
363
type Versioned < ' vers > = & ' vers str ;
317
364
0 commit comments