@@ -12,6 +12,7 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
12
12
use indexmap:: IndexMap ;
13
13
use integer_encoding:: { VarInt , VarIntReader } ;
14
14
use platform_value:: { Identifier , Value } ;
15
+ use platform_version:: version:: PlatformVersion ;
15
16
use rand:: distributions:: { Alphanumeric , Standard } ;
16
17
use rand:: rngs:: StdRng ;
17
18
use rand:: Rng ;
@@ -159,69 +160,93 @@ impl DocumentPropertyType {
159
160
}
160
161
}
161
162
162
- pub fn min_byte_size ( & self ) -> Option < u16 > {
163
+ pub fn min_byte_size (
164
+ & self ,
165
+ platform_version : & PlatformVersion ,
166
+ ) -> Result < Option < u16 > , ProtocolError > {
163
167
match self {
164
- DocumentPropertyType :: U128 => Some ( 16 ) ,
165
- DocumentPropertyType :: I128 => Some ( 16 ) ,
166
- DocumentPropertyType :: U64 => Some ( 8 ) ,
167
- DocumentPropertyType :: I64 => Some ( 8 ) ,
168
- DocumentPropertyType :: U32 => Some ( 4 ) ,
169
- DocumentPropertyType :: I32 => Some ( 4 ) ,
170
- DocumentPropertyType :: U16 => Some ( 2 ) ,
171
- DocumentPropertyType :: I16 => Some ( 2 ) ,
172
- DocumentPropertyType :: U8 => Some ( 1 ) ,
173
- DocumentPropertyType :: I8 => Some ( 1 ) ,
174
- DocumentPropertyType :: F64 => Some ( 8 ) ,
168
+ DocumentPropertyType :: U128 => Ok ( Some ( 16 ) ) ,
169
+ DocumentPropertyType :: I128 => Ok ( Some ( 16 ) ) ,
170
+ DocumentPropertyType :: U64 => Ok ( Some ( 8 ) ) ,
171
+ DocumentPropertyType :: I64 => Ok ( Some ( 8 ) ) ,
172
+ DocumentPropertyType :: U32 => Ok ( Some ( 4 ) ) ,
173
+ DocumentPropertyType :: I32 => Ok ( Some ( 4 ) ) ,
174
+ DocumentPropertyType :: U16 => Ok ( Some ( 2 ) ) ,
175
+ DocumentPropertyType :: I16 => Ok ( Some ( 2 ) ) ,
176
+ DocumentPropertyType :: U8 => Ok ( Some ( 1 ) ) ,
177
+ DocumentPropertyType :: I8 => Ok ( Some ( 1 ) ) ,
178
+ DocumentPropertyType :: F64 => Ok ( Some ( 8 ) ) ,
175
179
DocumentPropertyType :: String ( sizes) => match sizes. min_length {
176
- None => Some ( 0 ) ,
177
- Some ( size) => Some ( size * 4 ) ,
180
+ None => Ok ( Some ( 0 ) ) ,
181
+ Some ( size) => {
182
+ if platform_version. protocol_version > 8 {
183
+ match size. checked_mul ( 4 ) {
184
+ Some ( mul) => Ok ( Some ( mul) ) ,
185
+ None => Err ( ProtocolError :: Overflow ( "min_byte_size overflow" ) ) ,
186
+ }
187
+ } else {
188
+ Ok ( Some ( size. wrapping_mul ( 4 ) ) )
189
+ }
190
+ }
178
191
} ,
179
192
DocumentPropertyType :: ByteArray ( sizes) => match sizes. min_size {
180
- None => Some ( 0 ) ,
181
- Some ( size) => Some ( size) ,
193
+ None => Ok ( Some ( 0 ) ) ,
194
+ Some ( size) => Ok ( Some ( size) ) ,
182
195
} ,
183
- DocumentPropertyType :: Boolean => Some ( 1 ) ,
184
- DocumentPropertyType :: Date => Some ( 8 ) ,
196
+ DocumentPropertyType :: Boolean => Ok ( Some ( 1 ) ) ,
197
+ DocumentPropertyType :: Date => Ok ( Some ( 8 ) ) ,
185
198
DocumentPropertyType :: Object ( sub_fields) => sub_fields
186
199
. iter ( )
187
- . map ( |( _, sub_field) | sub_field. property_type . min_byte_size ( ) )
200
+ . map ( |( _, sub_field) | sub_field. property_type . min_byte_size ( platform_version ) )
188
201
. sum ( ) ,
189
- DocumentPropertyType :: Array ( _) => None ,
190
- DocumentPropertyType :: VariableTypeArray ( _) => None ,
191
- DocumentPropertyType :: Identifier => Some ( 32 ) ,
202
+ DocumentPropertyType :: Array ( _) => Ok ( None ) ,
203
+ DocumentPropertyType :: VariableTypeArray ( _) => Ok ( None ) ,
204
+ DocumentPropertyType :: Identifier => Ok ( Some ( 32 ) ) ,
192
205
}
193
206
}
194
207
195
- pub fn max_byte_size ( & self ) -> Option < u16 > {
208
+ pub fn max_byte_size (
209
+ & self ,
210
+ platform_version : & PlatformVersion ,
211
+ ) -> Result < Option < u16 > , ProtocolError > {
196
212
match self {
197
- DocumentPropertyType :: U128 => Some ( 16 ) ,
198
- DocumentPropertyType :: I128 => Some ( 16 ) ,
199
- DocumentPropertyType :: U64 => Some ( 8 ) ,
200
- DocumentPropertyType :: I64 => Some ( 8 ) ,
201
- DocumentPropertyType :: U32 => Some ( 4 ) ,
202
- DocumentPropertyType :: I32 => Some ( 4 ) ,
203
- DocumentPropertyType :: U16 => Some ( 2 ) ,
204
- DocumentPropertyType :: I16 => Some ( 2 ) ,
205
- DocumentPropertyType :: U8 => Some ( 1 ) ,
206
- DocumentPropertyType :: I8 => Some ( 1 ) ,
207
- DocumentPropertyType :: F64 => Some ( 8 ) ,
213
+ DocumentPropertyType :: U128 => Ok ( Some ( 16 ) ) ,
214
+ DocumentPropertyType :: I128 => Ok ( Some ( 16 ) ) ,
215
+ DocumentPropertyType :: U64 => Ok ( Some ( 8 ) ) ,
216
+ DocumentPropertyType :: I64 => Ok ( Some ( 8 ) ) ,
217
+ DocumentPropertyType :: U32 => Ok ( Some ( 4 ) ) ,
218
+ DocumentPropertyType :: I32 => Ok ( Some ( 4 ) ) ,
219
+ DocumentPropertyType :: U16 => Ok ( Some ( 2 ) ) ,
220
+ DocumentPropertyType :: I16 => Ok ( Some ( 2 ) ) ,
221
+ DocumentPropertyType :: U8 => Ok ( Some ( 1 ) ) ,
222
+ DocumentPropertyType :: I8 => Ok ( Some ( 1 ) ) ,
223
+ DocumentPropertyType :: F64 => Ok ( Some ( 8 ) ) ,
208
224
DocumentPropertyType :: String ( sizes) => match sizes. max_length {
209
- None => Some ( u16:: MAX ) ,
210
- Some ( size) => Some ( size * 4 ) ,
225
+ None => Ok ( Some ( u16:: MAX ) ) ,
226
+ Some ( size) => {
227
+ if platform_version. protocol_version > 8 {
228
+ match size. checked_mul ( 4 ) {
229
+ Some ( mul) => Ok ( Some ( mul) ) ,
230
+ None => Err ( ProtocolError :: Overflow ( "max_byte_size overflow" ) ) ,
231
+ }
232
+ } else {
233
+ Ok ( Some ( size. wrapping_mul ( 4 ) ) )
234
+ }
235
+ }
211
236
} ,
212
237
DocumentPropertyType :: ByteArray ( sizes) => match sizes. max_size {
213
- None => Some ( u16:: MAX ) ,
214
- Some ( size) => Some ( size) ,
238
+ None => Ok ( Some ( u16:: MAX ) ) ,
239
+ Some ( size) => Ok ( Some ( size) ) ,
215
240
} ,
216
- DocumentPropertyType :: Boolean => Some ( 1 ) ,
217
- DocumentPropertyType :: Date => Some ( 8 ) ,
241
+ DocumentPropertyType :: Boolean => Ok ( Some ( 1 ) ) ,
242
+ DocumentPropertyType :: Date => Ok ( Some ( 8 ) ) ,
218
243
DocumentPropertyType :: Object ( sub_fields) => sub_fields
219
244
. iter ( )
220
- . map ( |( _, sub_field) | sub_field. property_type . max_byte_size ( ) )
245
+ . map ( |( _, sub_field) | sub_field. property_type . max_byte_size ( platform_version ) )
221
246
. sum ( ) ,
222
- DocumentPropertyType :: Array ( _) => None ,
223
- DocumentPropertyType :: VariableTypeArray ( _) => None ,
224
- DocumentPropertyType :: Identifier => Some ( 32 ) ,
247
+ DocumentPropertyType :: Array ( _) => Ok ( None ) ,
248
+ DocumentPropertyType :: VariableTypeArray ( _) => Ok ( None ) ,
249
+ DocumentPropertyType :: Identifier => Ok ( Some ( 32 ) ) ,
225
250
}
226
251
}
227
252
@@ -259,60 +284,66 @@ impl DocumentPropertyType {
259
284
}
260
285
261
286
/// The middle size rounded down halfway between min and max size
262
- pub fn middle_size ( & self ) -> Option < u16 > {
263
- match self {
264
- DocumentPropertyType :: Array ( _) | DocumentPropertyType :: VariableTypeArray ( _) => {
265
- return None
266
- }
267
- _ => { }
287
+ pub fn middle_size ( & self , platform_version : & PlatformVersion ) -> Option < u16 > {
288
+ let min_size = self . min_size ( ) ?;
289
+ let max_size = self . max_size ( ) ?;
290
+ if platform_version. protocol_version > 8 {
291
+ Some ( ( ( min_size as u32 + max_size as u32 ) / 2 ) as u16 )
292
+ } else {
293
+ Some ( min_size. wrapping_add ( max_size) / 2 )
268
294
}
269
- let min_size = self . min_size ( ) . unwrap ( ) ;
270
- let max_size = self . max_size ( ) . unwrap ( ) ;
271
- Some ( ( min_size + max_size) / 2 )
272
295
}
273
296
274
297
/// The middle size rounded up halfway between min and max size
275
- pub fn middle_size_ceil ( & self ) -> Option < u16 > {
276
- match self {
277
- DocumentPropertyType :: Array ( _) | DocumentPropertyType :: VariableTypeArray ( _) => {
278
- return None
279
- }
280
- _ => { }
298
+ pub fn middle_size_ceil ( & self , platform_version : & PlatformVersion ) -> Option < u16 > {
299
+ let min_size = self . min_size ( ) ?;
300
+ let max_size = self . max_size ( ) ?;
301
+ if platform_version. protocol_version > 8 {
302
+ Some ( ( ( min_size as u32 + max_size as u32 + 1 ) / 2 ) as u16 )
303
+ } else {
304
+ Some ( min_size. wrapping_add ( max_size) . wrapping_add ( 1 ) / 2 )
281
305
}
282
- let min_size = self . min_size ( ) . unwrap ( ) ;
283
- let max_size = self . max_size ( ) . unwrap ( ) ;
284
- Some ( ( min_size + max_size + 1 ) / 2 )
285
306
}
286
307
287
308
/// The middle size rounded down halfway between min and max byte size
288
- pub fn middle_byte_size ( & self ) -> Option < u16 > {
289
- match self {
290
- DocumentPropertyType :: Array ( _) | DocumentPropertyType :: VariableTypeArray ( _) => {
291
- return None
292
- }
293
- _ => { }
309
+ pub fn middle_byte_size (
310
+ & self ,
311
+ platform_version : & PlatformVersion ,
312
+ ) -> Result < Option < u16 > , ProtocolError > {
313
+ let Some ( min_size) = self . min_byte_size ( platform_version) ? else {
314
+ return Ok ( None ) ;
315
+ } ;
316
+ let Some ( max_size) = self . max_byte_size ( platform_version) ? else {
317
+ return Ok ( None ) ;
318
+ } ;
319
+ if platform_version. protocol_version > 8 {
320
+ Ok ( Some ( ( ( min_size as u32 + max_size as u32 ) / 2 ) as u16 ) )
321
+ } else {
322
+ Ok ( Some ( min_size. wrapping_add ( max_size) / 2 ) )
294
323
}
295
- let min_size = self . min_byte_size ( ) . unwrap ( ) ;
296
- let max_size = self . max_byte_size ( ) . unwrap ( ) ;
297
- Some ( ( min_size + max_size) / 2 )
298
324
}
299
325
300
326
/// The middle size rounded up halfway between min and max byte size
301
- pub fn middle_byte_size_ceil ( & self ) -> Option < u16 > {
302
- match self {
303
- DocumentPropertyType :: Array ( _) | DocumentPropertyType :: VariableTypeArray ( _) => {
304
- return None
305
- }
306
- _ => { }
327
+ pub fn middle_byte_size_ceil (
328
+ & self ,
329
+ platform_version : & PlatformVersion ,
330
+ ) -> Result < Option < u16 > , ProtocolError > {
331
+ let Some ( min_size) = self . min_byte_size ( platform_version) ? else {
332
+ return Ok ( None ) ;
333
+ } ;
334
+ let Some ( max_size) = self . max_byte_size ( platform_version) ? else {
335
+ return Ok ( None ) ;
336
+ } ;
337
+ if platform_version. protocol_version > 8 {
338
+ Ok ( Some ( ( ( min_size as u32 + max_size as u32 + 1 ) / 2 ) as u16 ) )
339
+ } else {
340
+ Ok ( Some ( min_size. wrapping_add ( max_size) . wrapping_add ( 1 ) / 2 ) )
307
341
}
308
- let min_size = self . min_byte_size ( ) . unwrap ( ) as u32 ;
309
- let max_size = self . max_byte_size ( ) . unwrap ( ) as u32 ;
310
- Some ( ( ( min_size + max_size + 1 ) / 2 ) as u16 )
311
342
}
312
343
313
344
pub fn random_size ( & self , rng : & mut StdRng ) -> u16 {
314
- let min_size = self . min_size ( ) . unwrap ( ) ;
315
- let max_size = self . max_size ( ) . unwrap ( ) ;
345
+ let min_size = self . min_size ( ) . unwrap_or_default ( ) ;
346
+ let max_size = self . max_size ( ) . unwrap_or_default ( ) ;
316
347
rng. gen_range ( min_size..=max_size)
317
348
}
318
349
0 commit comments