@@ -30,6 +30,7 @@ pub struct Column {
30
30
pub value_type : ValueType ,
31
31
pub seen_count : usize ,
32
32
pub order : usize ,
33
+ pub cache_pointer_index : Vec < Option < isize > > ,
33
34
}
34
35
35
36
impl Hash for Column {
@@ -46,6 +47,7 @@ impl Column {
46
47
value_type,
47
48
seen_count : 0 ,
48
49
order : 0 ,
50
+ cache_pointer_index : vec ! [ ] ,
49
51
}
50
52
}
51
53
}
@@ -95,8 +97,8 @@ impl ScrollToRowMode {
95
97
#[ derive( Default ) ]
96
98
pub struct ArrayTable {
97
99
all_columns : Vec < Column > ,
98
- column_selected : Vec < Column > ,
99
- column_pinned : Vec < Column > ,
100
+ column_selected : RefCell < Vec < Column > > ,
101
+ column_pinned : RefCell < Vec < Column > > ,
100
102
pub max_depth : u8 ,
101
103
last_parsed_max_depth : u8 ,
102
104
parse_result : Option < ParseResult < String > > ,
@@ -167,7 +169,7 @@ impl super::View<ArrayResponse> for ArrayTable {
167
169
self . matching_columns . clear ( ) ;
168
170
self . matching_column_selected = 0 ;
169
171
if !self . scroll_to_column . is_empty ( ) {
170
- for ( index, column) in self . column_selected . iter ( ) . enumerate ( ) {
172
+ for ( index, column) in self . column_selected . borrow ( ) . iter ( ) . enumerate ( ) {
171
173
if column. name . to_lowercase ( ) . eq ( & concat_string ! ( "/" , & self . scroll_to_column. to_lowercase( ) ) )
172
174
|| column. name . to_lowercase ( ) . contains ( & self . scroll_to_column . to_lowercase ( ) ) {
173
175
self . matching_columns . push ( index) ;
@@ -243,15 +245,15 @@ impl ArrayTable {
243
245
pub fn new ( parse_result : Option < ParseResult < String > > , nodes : Vec < JsonArrayEntries < String > > , all_columns : Vec < Column > , depth : u8 , parent_pointer : String ) -> Self {
244
246
let last_parsed_max_depth = parse_result. as_ref ( ) . map_or ( depth, |p| p. parsing_max_depth ) ;
245
247
Self {
246
- column_selected : Self :: selected_columns ( & all_columns, depth) ,
248
+ column_selected : RefCell :: new ( Self :: selected_columns ( & all_columns, depth) ) ,
247
249
all_columns,
248
250
max_depth : depth,
249
251
filtered_nodes : ( 0 ..nodes. len ( ) ) . collect :: < Vec < usize > > ( ) ,
250
252
nodes,
251
253
parse_result,
252
254
// states
253
255
next_frame_reset_scroll : false ,
254
- column_pinned : vec ! [ Column :: new( "/#" . to_string( ) , ValueType :: Number ) ] ,
256
+ column_pinned : RefCell :: new ( vec ! [ Column :: new( "/#" . to_string( ) , ValueType :: Number ) ] ) ,
255
257
scroll_y : 0.0 ,
256
258
hovered_row_index : None ,
257
259
columns_offset : vec ! [ ] ,
@@ -306,15 +308,17 @@ impl ArrayTable {
306
308
pub fn update_selected_columns ( & mut self , depth : u8 ) -> Option < usize > {
307
309
if depth <= self . last_parsed_max_depth {
308
310
let mut column_selected = Self :: selected_columns ( & self . all_columns , depth) ;
309
- column_selected. retain ( |c| !self . column_pinned . contains ( c) ) ;
310
- self . column_selected = column_selected;
311
- if self . column_selected . is_empty ( ) {
312
- self . column_selected . push ( Column {
311
+ column_selected. retain ( |c| !self . column_pinned . borrow ( ) . contains ( c) ) ;
312
+ let is_empty = column_selected. is_empty ( ) ;
313
+ * self . column_selected . borrow_mut ( ) = column_selected;
314
+ if is_empty {
315
+ self . column_selected . borrow_mut ( ) . push ( Column {
313
316
name : "" . to_string ( ) ,
314
317
depth,
315
318
value_type : Default :: default ( ) ,
316
319
seen_count : 0 ,
317
320
order : 0 ,
321
+ cache_pointer_index : vec ! [ ] ,
318
322
} )
319
323
}
320
324
None
@@ -323,8 +327,8 @@ impl ArrayTable {
323
327
let ( new_json_array, new_columns, new_max_depth) = crate :: parser:: change_depth_array ( previous_parse_result, mem:: take ( & mut self . nodes ) , depth as usize ) . unwrap ( ) ;
324
328
self . all_columns = new_columns;
325
329
let mut column_selected = Self :: selected_columns ( & self . all_columns , depth) ;
326
- column_selected. retain ( |c| !self . column_pinned . contains ( c) ) ;
327
- self . column_selected = column_selected;
330
+ column_selected. retain ( |c| !self . column_pinned . borrow ( ) . contains ( c) ) ;
331
+ * self . column_selected . borrow_mut ( ) = column_selected;
328
332
self . nodes = new_json_array;
329
333
self . last_parsed_max_depth = depth;
330
334
self . parse_result . as_mut ( ) . unwrap ( ) . parsing_max_depth = depth;
@@ -418,8 +422,9 @@ impl ArrayTable {
418
422
}
419
423
table = table. vertical_scroll_offset ( self . scroll_y ) ;
420
424
421
- let columns_count = if pinned_column_table { self . column_pinned . len ( ) } else { self . column_selected . len ( ) } ;
422
- let columns = if pinned_column_table { & self . column_pinned } else { & self . column_selected } ;
425
+ let columns = if pinned_column_table { self . column_pinned . borrow ( ) } else { self . column_selected . borrow ( ) } ;
426
+ let columns_count = columns. len ( ) ;
427
+
423
428
if columns_count <= 3 {
424
429
for i in 0 ..columns_count {
425
430
if pinned_column_table && i == 0 {
@@ -438,6 +443,7 @@ impl ArrayTable {
438
443
table = table. column ( Column :: initial ( ( columns[ i] . name . len ( ) + 3 ) . max ( 10 ) as f32 * text_width) . clip ( true ) . resizable ( true ) ) ;
439
444
}
440
445
}
446
+ drop ( columns) ;
441
447
442
448
let mut request_repaint = false ;
443
449
let search_highlight_row = if !self . matching_rows . is_empty ( ) {
@@ -466,12 +472,12 @@ impl ArrayTable {
466
472
}
467
473
468
474
fn header ( & mut self , pinned_column_table : bool , mut header : TableRow ) {
469
- // Mutation after interaction
475
+ // Mutation after interaction
470
476
let mut clicked_filter_non_null_column: Option < String > = None ;
471
477
let mut clicked_filter_column_value: Option < ( String , String ) > = None ;
472
478
let mut pinned_column: Option < usize > = None ;
473
479
header. cols ( true , |ui, index| {
474
- let columns = if pinned_column_table { & self . column_pinned } else { & self . column_selected } ;
480
+ let columns = if pinned_column_table { self . column_pinned . borrow ( ) } else { self . column_selected . borrow ( ) } ;
475
481
let column = columns. get ( index) . unwrap ( ) ;
476
482
let name = column. name . clone ( ) . to_string ( ) ;
477
483
let strong = Label :: new ( WidgetText :: RichText ( egui:: RichText :: from ( & name) ) ) ;
@@ -532,13 +538,14 @@ impl ArrayTable {
532
538
Some ( response. inner )
533
539
} ) ;
534
540
if let Some ( pinned_column) = pinned_column {
541
+ let mut column_selected_mut = self . column_selected . borrow_mut ( ) ;
535
542
if pinned_column_table {
536
- let column = self . column_pinned . remove ( pinned_column) ;
537
- self . column_selected . push ( column) ;
538
- self . column_selected . sort ( ) ;
543
+ let column = self . column_pinned . borrow_mut ( ) . remove ( pinned_column) ;
544
+ column_selected_mut . push ( column) ;
545
+ column_selected_mut . sort ( ) ;
539
546
} else {
540
- let column = self . column_selected . remove ( pinned_column) ;
541
- self . column_pinned . push ( column) ;
547
+ let column = column_selected_mut . remove ( pinned_column) ;
548
+ self . column_pinned . borrow_mut ( ) . push ( column) ;
542
549
}
543
550
}
544
551
if let Some ( clicked_column) = clicked_filter_non_null_column {
@@ -556,16 +563,20 @@ impl ArrayTable {
556
563
let mut focused_cell = None ;
557
564
let mut focused_changed = false ;
558
565
let mut updated_value: Option < ( PointerKey , String ) > = None ;
559
- let columns = if pinned_column_table { & self . column_pinned } else { & self . column_selected } ;
566
+ let mut columns = if pinned_column_table { self . column_pinned . borrow_mut ( ) } else { self . column_selected . borrow_mut ( ) } ;
560
567
let hovered_row_index = body. rows ( text_height, self . filtered_nodes . len ( ) , |mut row| {
561
568
let table_row_index = row. index ( ) ;
562
569
let row_index = self . filtered_nodes [ table_row_index] ;
563
570
let node = self . nodes ( ) . get ( row_index) ;
564
571
565
572
if let Some ( row_data) = node. as_ref ( ) {
566
573
row. cols ( false , |ui, col_index| {
574
+ if pinned_column_table && col_index == 0 {
575
+ let label = Label :: new ( row_data. entries ( ) [ 0 ] . pointer . index . to_string ( ) ) . sense ( Sense :: click ( ) ) ;
576
+ return Some ( label. ui ( ui) ) ;
577
+ }
567
578
let cell_id = row_index * columns. len ( ) + col_index + if pinned_column_table { self . seed1 } else { self . seed2 } ;
568
- let cell_data = self . get_pointer ( columns, & row_data. entries ( ) , col_index, row_data. index ( ) ) ;
579
+ let cell_data = self . get_pointer2 ( columns. as_mut ( ) , & row_data. entries ( ) , col_index, row_data. index ( ) ) ;
569
580
let mut editing_index = self . editing_index . borrow_mut ( ) ;
570
581
if editing_index. is_some ( ) && editing_index. unwrap ( ) == ( col_index, row_index, pinned_column_table) {
571
582
let ref_mut = & mut * self . editing_value . borrow_mut ( ) ;
@@ -585,10 +596,7 @@ impl ArrayTable {
585
596
} else if let Some ( entry) = cell_data {
586
597
let is_array = matches ! ( entry. pointer. value_type, ValueType :: Array ( _) ) ;
587
598
let is_object = matches ! ( entry. pointer. value_type, ValueType :: Object ( _) ) ;
588
- if pinned_column_table && col_index == 0 {
589
- let label = Label :: new ( entry. pointer . index . to_string ( ) ) . sense ( Sense :: click ( ) ) ;
590
- return Some ( label. ui ( ui) ) ;
591
- } else if let Some ( value) = entry. value . as_ref ( ) {
599
+ if let Some ( value) = entry. value . as_ref ( ) {
592
600
if !matches ! ( entry. pointer. value_type, ValueType :: Null ) {
593
601
let mut label = if is_array || is_object {
594
602
Label :: new ( value. replace ( '\n' , "" ) ) // maybe we want cache
@@ -726,6 +734,7 @@ impl ArrayTable {
726
734
Some ( value)
727
735
} ;
728
736
let ( _, row_index, _) = editing_index. unwrap ( ) ;
737
+ drop ( columns) ;
729
738
if self . is_sub_table {
730
739
let updated_pointer = pointer. clone ( ) ;
731
740
let value_changed = self . update_value ( FlatJsonValue { pointer : updated_pointer. clone ( ) , value : value. clone ( ) } , row_index, false ) ;
@@ -810,7 +819,31 @@ impl ArrayTable {
810
819
value_changed
811
820
}
812
821
813
- // C
822
+
823
+ #[ inline]
824
+ fn get_pointer2 < ' a > ( & self , columns : & mut Vec < Column > , data : & & ' a Vec < FlatJsonValue < String > > , index : usize , row_index : usize ) -> Option < & ' a FlatJsonValue < String > > {
825
+ if let Some ( column) = columns. get_mut ( index) {
826
+ if let Some ( pointer_index) = column. cache_pointer_index [ row_index] {
827
+ if pointer_index < 0 {
828
+ return None ;
829
+ }
830
+ return Some ( & data[ pointer_index as usize ] ) ;
831
+ } else {
832
+ let key = & column. name ;
833
+ let key = Self :: pointer_key ( & self . parent_pointer , row_index, key) ;
834
+ let position = data. iter ( ) . position ( |entry| {
835
+ entry. pointer . pointer . eq ( & key)
836
+ } ) ;
837
+ if position. is_some ( ) {
838
+ column. cache_pointer_index [ row_index] = Some ( position. unwrap ( ) as isize ) ;
839
+ } else {
840
+ column. cache_pointer_index [ row_index] = Some ( -1 ) ;
841
+ return None ;
842
+ }
843
+ }
844
+ }
845
+ None
846
+ }
814
847
815
848
#[ inline]
816
849
fn get_pointer < ' a > ( & self , columns : & Vec < Column > , data : & & ' a Vec < FlatJsonValue < String > > , index : usize , row_index : usize ) -> Option < & ' a FlatJsonValue < String > > {
0 commit comments