@@ -584,6 +584,21 @@ impl ParentState<'_> {
584
584
| ParentState :: List { buffer, .. } => buffer. offset ( ) ,
585
585
}
586
586
}
587
+
588
+ // return the current index of the undelying metadata buffer at the time of calling this method.
589
+ fn metadata_current_offset ( & self ) -> usize {
590
+ match self {
591
+ ParentState :: Variant {
592
+ metadata_builder, ..
593
+ }
594
+ | ParentState :: Object {
595
+ metadata_builder, ..
596
+ }
597
+ | ParentState :: List {
598
+ metadata_builder, ..
599
+ } => metadata_builder. metadata_buffer . len ( ) ,
600
+ }
601
+ }
587
602
}
588
603
589
604
/// Top level builder for [`Variant`] values
@@ -1065,6 +1080,9 @@ pub struct ObjectBuilder<'a> {
1065
1080
fields : IndexMap < u32 , usize > , // (field_id, offset)
1066
1081
/// the starting offset in the parent's buffer where this object starts
1067
1082
object_start_offset : usize ,
1083
+ /// the starting offset in the parent's metadata buffer where this object starts
1084
+ /// used to truncate the written fields in `drop` if the current object has not been finished
1085
+ object_meta_start_offset : usize ,
1068
1086
/// whether the object has been finished, the written content of the current object
1069
1087
/// will be truncated in `drop` if `has_been_finished` is false
1070
1088
has_been_finished : bool ,
@@ -1076,11 +1094,13 @@ pub struct ObjectBuilder<'a> {
1076
1094
impl < ' a > ObjectBuilder < ' a > {
1077
1095
fn new ( parent_state : ParentState < ' a > , validate_unique_fields : bool ) -> Self {
1078
1096
let start_offset = parent_state. buffer_current_offset ( ) ;
1097
+ let meta_start_offset = parent_state. metadata_current_offset ( ) ;
1079
1098
Self {
1080
1099
parent_state,
1081
1100
fields : IndexMap :: new ( ) ,
1082
1101
object_start_offset : start_offset,
1083
1102
has_been_finished : false ,
1103
+ object_meta_start_offset : meta_start_offset,
1084
1104
validate_unique_fields,
1085
1105
duplicate_fields : HashSet :: new ( ) ,
1086
1106
}
@@ -1269,6 +1289,11 @@ impl Drop for ObjectBuilder<'_> {
1269
1289
. buffer ( )
1270
1290
. inner_mut ( )
1271
1291
. truncate ( self . object_start_offset ) ;
1292
+
1293
+ self . parent_state
1294
+ . metadata_builder ( )
1295
+ . field_names
1296
+ . truncate ( self . object_meta_start_offset ) ;
1272
1297
}
1273
1298
}
1274
1299
}
@@ -2542,8 +2567,7 @@ mod tests {
2542
2567
// The original builder should be unchanged
2543
2568
let ( metadata, value) = builder. finish ( ) ;
2544
2569
let metadata = VariantMetadata :: try_new ( & metadata) . unwrap ( ) ;
2545
- assert_eq ! ( metadata. len( ) , 1 ) ;
2546
- assert_eq ! ( & metadata[ 0 ] , "name" ) ; // not rolled back
2570
+ assert ! ( metadata. is_empty( ) ) ; // rolled back
2547
2571
2548
2572
let variant = Variant :: try_new_with_metadata ( metadata, & value) . unwrap ( ) ;
2549
2573
assert_eq ! ( variant, Variant :: Int8 ( 42 ) ) ;
@@ -2617,8 +2641,7 @@ mod tests {
2617
2641
list_builder. finish ( ) ;
2618
2642
let ( metadata, value) = builder. finish ( ) ;
2619
2643
let metadata = VariantMetadata :: try_new ( & metadata) . unwrap ( ) ;
2620
- assert_eq ! ( metadata. len( ) , 1 ) ;
2621
- assert_eq ! ( & metadata[ 0 ] , "name" ) ; // not rolled back
2644
+ assert ! ( metadata. is_empty( ) ) ;
2622
2645
2623
2646
let variant = Variant :: try_new_with_metadata ( metadata, & value) . unwrap ( ) ;
2624
2647
let list = variant. as_list ( ) . unwrap ( ) ;
@@ -2646,8 +2669,8 @@ mod tests {
2646
2669
// Only the second attempt should appear in the final variant
2647
2670
let ( metadata, value) = builder. finish ( ) ;
2648
2671
let metadata = VariantMetadata :: try_new ( & metadata) . unwrap ( ) ;
2649
- assert_eq ! ( metadata. len( ) , 1 ) ;
2650
- assert_eq ! ( & metadata[ 0 ] , "name" ) ; // not rolled back
2672
+ assert_eq ! ( metadata. len( ) , 1 ) ; // rolled back
2673
+ assert_eq ! ( & metadata[ 0 ] , "name" ) ;
2651
2674
2652
2675
let variant = Variant :: try_new_with_metadata ( metadata, & value) . unwrap ( ) ;
2653
2676
assert_eq ! ( variant, Variant :: Int8 ( 2 ) ) ;
@@ -2700,9 +2723,7 @@ mod tests {
2700
2723
// Only the second attempt should appear in the final variant
2701
2724
let ( metadata, value) = builder. finish ( ) ;
2702
2725
let metadata = VariantMetadata :: try_new ( & metadata) . unwrap ( ) ;
2703
- assert_eq ! ( metadata. len( ) , 2 ) ;
2704
- assert_eq ! ( & metadata[ 0 ] , "first" ) ;
2705
- assert_eq ! ( & metadata[ 1 ] , "nested" ) ; // not rolled back
2726
+ assert ! ( metadata. is_empty( ) ) ; // rolled back
2706
2727
2707
2728
let variant = Variant :: try_new_with_metadata ( metadata, & value) . unwrap ( ) ;
2708
2729
assert_eq ! ( variant, Variant :: Int8 ( 2 ) ) ;
@@ -2725,15 +2746,12 @@ mod tests {
2725
2746
object_builder. finish ( ) . unwrap ( ) ;
2726
2747
let ( metadata, value) = builder. finish ( ) ;
2727
2748
let metadata = VariantMetadata :: try_new ( & metadata) . unwrap ( ) ;
2728
- assert_eq ! ( metadata. len( ) , 3 ) ;
2729
- assert_eq ! ( & metadata[ 0 ] , "first" ) ;
2730
- assert_eq ! ( & metadata[ 1 ] , "name" ) ; // not rolled back
2731
- assert_eq ! ( & metadata[ 2 ] , "second" ) ;
2749
+ assert_eq ! ( metadata. len( ) , 1 ) ; // the fields of nested_object_builder has been rolled back
2750
+ assert_eq ! ( & metadata[ 0 ] , "second" ) ;
2732
2751
2733
2752
let variant = Variant :: try_new_with_metadata ( metadata, & value) . unwrap ( ) ;
2734
2753
let obj = variant. as_object ( ) . unwrap ( ) ;
2735
- assert_eq ! ( obj. len( ) , 2 ) ;
2736
- assert_eq ! ( obj. get( "first" ) , Some ( Variant :: Int8 ( 1 ) ) ) ;
2754
+ assert_eq ! ( obj. len( ) , 1 ) ;
2737
2755
assert_eq ! ( obj. get( "second" ) , Some ( Variant :: Int8 ( 2 ) ) ) ;
2738
2756
}
2739
2757
@@ -2756,10 +2774,7 @@ mod tests {
2756
2774
// Only the second attempt should appear in the final variant
2757
2775
let ( metadata, value) = builder. finish ( ) ;
2758
2776
let metadata = VariantMetadata :: try_new ( & metadata) . unwrap ( ) ;
2759
- assert_eq ! ( metadata. len( ) , 3 ) ;
2760
- assert_eq ! ( & metadata[ 0 ] , "first" ) ; // not rolled back
2761
- assert_eq ! ( & metadata[ 1 ] , "name" ) ; // not rolled back
2762
- assert_eq ! ( & metadata[ 2 ] , "nested" ) ; // not rolled back
2777
+ assert_eq ! ( metadata. len( ) , 0 ) ; // rolled back
2763
2778
2764
2779
let variant = Variant :: try_new_with_metadata ( metadata, & value) . unwrap ( ) ;
2765
2780
assert_eq ! ( variant, Variant :: Int8 ( 2 ) ) ;
0 commit comments