@@ -990,7 +990,7 @@ impl<'m, 'v> VariantBuilderExt<'m, 'v> for VariantBuilder {
990
990
991
991
#[ cfg( test) ]
992
992
mod tests {
993
- use crate :: VariantMetadata ;
993
+ use crate :: { utils :: first_byte_from_slice , VariantMetadata } ;
994
994
995
995
use super :: * ;
996
996
@@ -2171,4 +2171,116 @@ mod tests {
2171
2171
let variant = Variant :: try_new_with_metadata ( metadata, & value) . unwrap ( ) ;
2172
2172
assert_eq ! ( variant, Variant :: Int8 ( 2 ) ) ;
2173
2173
}
2174
+
2175
+ fn test_variant_object_with_count ( count : i32 , expected_field_id_size_minus_one : u8 ) {
2176
+ let mut builder = VariantBuilder :: new ( ) ;
2177
+ let mut obj = builder. new_object ( ) ;
2178
+
2179
+ for val in 0 ..count {
2180
+ let key = format ! ( "id_{}" , val) ;
2181
+ obj. insert ( & key, val) ;
2182
+ }
2183
+
2184
+ obj. finish ( ) . unwrap ( ) ;
2185
+ let ( metadata, value) = builder. finish ( ) ;
2186
+ let variant = Variant :: try_new ( & metadata, & value) . unwrap ( ) ;
2187
+
2188
+ if let Variant :: Object ( obj) = variant {
2189
+ assert_eq ! ( obj. len( ) , count as usize ) ;
2190
+ assert_eq ! ( obj. get( & format!( "id_{}" , 0 ) ) . unwrap( ) , Variant :: Int32 ( 0 ) ) ;
2191
+ assert_eq ! (
2192
+ obj. get( & format!( "id_{}" , count - 1 ) ) . unwrap( ) ,
2193
+ Variant :: Int32 ( count - 1 )
2194
+ ) ;
2195
+
2196
+ let header_byte = first_byte_from_slice ( & value) . unwrap ( ) ;
2197
+ let value_header = header_byte >> 2 ;
2198
+ let field_id_size_minus_one = ( value_header >> 2 ) & 0x03 ;
2199
+ assert_eq ! (
2200
+ field_id_size_minus_one, expected_field_id_size_minus_one,
2201
+ "Expected {}-byte field IDs" ,
2202
+ expected_field_id_size_minus_one
2203
+ ) ;
2204
+ } else {
2205
+ panic ! ( "Expected object variant" ) ;
2206
+ }
2207
+ }
2208
+
2209
+ #[ test]
2210
+ fn test_variant_object_257_elements ( ) {
2211
+ test_variant_object_with_count ( 2_i32 . pow ( 8 ) + 1 , 1 ) ; // 2^8 + 1, expected 2-byte field IDs
2212
+ }
2213
+
2214
+ #[ test]
2215
+ fn test_variant_object_65537_elements ( ) {
2216
+ test_variant_object_with_count ( 2_i32 . pow ( 16 ) + 1 , 2 ) ; // 2^16 + 1, expected 3-byte field IDs
2217
+ }
2218
+
2219
+ #[ test]
2220
+ #[ ignore]
2221
+ fn test_variant_object_16777217_elements ( ) {
2222
+ test_variant_object_with_count ( 2_i32 . pow ( 24 ) + 1 , 3 ) ; // 2^24 + 1, expected 4-byte field IDs
2223
+ }
2224
+
2225
+ #[ test]
2226
+ fn test_variant_object_small_sizes_255_elements ( ) {
2227
+ // should pass
2228
+ test_variant_object_with_count ( 255 , 0 ) ;
2229
+ }
2230
+
2231
+ fn test_variant_object_with_large_data (
2232
+ data_size_per_field : usize ,
2233
+ expected_field_offset_size_minus_one : u8 ,
2234
+ ) {
2235
+ let num_fields = 20 ;
2236
+ let mut builder = VariantBuilder :: new ( ) ;
2237
+ let mut obj = builder. new_object ( ) ;
2238
+
2239
+ let str_val = "a" . repeat ( data_size_per_field) ;
2240
+
2241
+ for val in 0 ..num_fields {
2242
+ let key = format ! ( "id_{}" , val) ;
2243
+ obj. insert ( & key, str_val. as_str ( ) ) ;
2244
+ }
2245
+
2246
+ obj. finish ( ) . unwrap ( ) ;
2247
+ let ( metadata, value) = builder. finish ( ) ;
2248
+ let variant = Variant :: try_new ( & metadata, & value) . unwrap ( ) ;
2249
+
2250
+ if let Variant :: Object ( obj) = variant {
2251
+ assert_eq ! ( obj. len( ) , num_fields) ;
2252
+ let header_byte = first_byte_from_slice ( & value) . unwrap ( ) ;
2253
+ let value_header = header_byte >> 2 ;
2254
+ let field_offset_size_minus_one = value_header & 0x03 ;
2255
+ assert_eq ! (
2256
+ field_offset_size_minus_one,
2257
+ expected_field_offset_size_minus_one,
2258
+ "Expected {}-byte field offsets, got {}-byte field offsets" ,
2259
+ expected_field_offset_size_minus_one + 1 ,
2260
+ field_offset_size_minus_one + 1
2261
+ ) ;
2262
+ } else {
2263
+ panic ! ( "Expected object variant" ) ;
2264
+ }
2265
+ }
2266
+
2267
+ #[ test]
2268
+ fn test_variant_object_child_data_0_byte_offsets_minus_one ( ) {
2269
+ test_variant_object_with_large_data ( 10 , 0 ) ;
2270
+ }
2271
+
2272
+ #[ test]
2273
+ fn test_variant_object_256_bytes_child_data_3_byte_offsets ( ) {
2274
+ test_variant_object_with_large_data ( 256 + 1 , 1 ) ; // 2^8 - 2^16 elements
2275
+ }
2276
+
2277
+ #[ test]
2278
+ fn test_variant_object_16777216_bytes_child_data_4_byte_offsets ( ) {
2279
+ test_variant_object_with_large_data ( 65536 + 1 , 2 ) ; // 2^16 - 2^24 elements
2280
+ }
2281
+
2282
+ #[ test]
2283
+ fn test_variant_object_65535_bytes_child_data_2_byte_offsets ( ) {
2284
+ test_variant_object_with_large_data ( 16777216 + 1 , 3 ) ; // 2^24
2285
+ }
2174
2286
}
0 commit comments