From 47e6ace22ae62b97c643a6b22c8a136d453aa23f Mon Sep 17 00:00:00 2001 From: InAnYan Date: Tue, 19 Nov 2024 13:28:31 +0200 Subject: [PATCH 1/5] Preliminary --- module/core/format_tools/src/format/as_table.rs | 14 +++++++------- module/core/format_tools/tests/tests.rs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/module/core/format_tools/src/format/as_table.rs b/module/core/format_tools/src/format/as_table.rs index 7409b42952..d269556525 100644 --- a/module/core/format_tools/src/format/as_table.rs +++ b/module/core/format_tools/src/format/as_table.rs @@ -32,7 +32,7 @@ mod private ) where RowKey : table::RowKey, - Row : Cells< CellKey>, + Row : Cells< CellKey >, CellKey : table::CellKey + ?Sized, // CellRepr : table::CellRepr ; @@ -41,7 +41,7 @@ mod private AsTable< 'table, Table, RowKey, Row, CellKey> where RowKey : table::RowKey, - Row : Cells< CellKey>, + Row : Cells< CellKey >, CellKey : table::CellKey + ?Sized, // CellRepr : table::CellRepr, { @@ -56,7 +56,7 @@ mod private for AsTable< 'table, Table, RowKey, Row, CellKey> where RowKey : table::RowKey, - Row : Cells< CellKey>, + Row : Cells< CellKey >, CellKey : table::CellKey + ?Sized, // CellRepr : table::CellRepr, { @@ -70,7 +70,7 @@ mod private for AsTable< 'table, Table, RowKey, Row, CellKey> where RowKey : table::RowKey, - Row : Cells< CellKey>, + Row : Cells< CellKey >, CellKey : table::CellKey + ?Sized, // CellRepr : table::CellRepr, { @@ -86,7 +86,7 @@ mod private for AsTable< 'table, Table, RowKey, Row, CellKey> where RowKey : table::RowKey, - Row : Cells< CellKey>, + Row : Cells< CellKey >, CellKey : table::CellKey + ?Sized, // CellRepr : table::CellRepr, { @@ -101,7 +101,7 @@ mod private where Table : fmt::Debug, RowKey : table::RowKey, - Row : Cells< CellKey>, + Row : Cells< CellKey >, CellKey : table::CellKey + ?Sized, // CellRepr : table::CellRepr, { @@ -146,7 +146,7 @@ mod private for AsTable< 'table, Table, RowKey, Row, CellKey> where RowKey : table::RowKey, - Row : Cells< CellKey>, + Row : Cells< CellKey >, CellKey : table::CellKey + ?Sized, // CellRepr : table::CellRepr, Self : Copy, diff --git a/module/core/format_tools/tests/tests.rs b/module/core/format_tools/tests/tests.rs index 4fca6dbc07..c8e636300b 100644 --- a/module/core/format_tools/tests/tests.rs +++ b/module/core/format_tools/tests/tests.rs @@ -1,6 +1,6 @@ //! Primary tests. -#![ feature( trace_macros ) ] +// #![ feature( trace_macros ) ] #![ allow( unused_imports ) ] use format_tools as the_module; From 2b34a1f188c85e5ff7f56ca4595196862f77bfe5 Mon Sep 17 00:00:00 2001 From: InAnYan Date: Tue, 19 Nov 2024 15:14:38 +0200 Subject: [PATCH 2/5] Working on --- module/core/format_tools/src/format/table.rs | 11 +- .../format_tools/tests/inc/collection_test.rs | 102 ++++++++++++++++++ 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/module/core/format_tools/src/format/table.rs b/module/core/format_tools/src/format/table.rs index 27e44ca0e5..6be2d185ca 100644 --- a/module/core/format_tools/src/format/table.rs +++ b/module/core/format_tools/src/format/table.rs @@ -12,7 +12,11 @@ mod private // fmt, borrow::Borrow, }; - use std::borrow::Cow; + use std:: + { + borrow::Cow, + collections::HashMap, + }; use reflect_tools:: { IteratorTrait, @@ -72,9 +76,12 @@ mod private // = - /// Marker trait to tag structures for whcih table trait deducing should be done from trait Fields, which is reflection. + /// Marker trait to tag structures for which table trait deducing should be done from trait Fields, which is reflection. pub trait TableWithFields {} + impl TableWithFields for HashMap< String, String > {} + impl TableWithFields for HashMap< &str, String > {} + // = /// A trait for iterating over all cells of a row. diff --git a/module/core/format_tools/tests/inc/collection_test.rs b/module/core/format_tools/tests/inc/collection_test.rs index 6b17ce0975..59d4d9e5e1 100644 --- a/module/core/format_tools/tests/inc/collection_test.rs +++ b/module/core/format_tools/tests/inc/collection_test.rs @@ -401,3 +401,105 @@ fn llist_basic() } // qqq : xxx : implement for other containers + +#[ test ] +fn vec_of_hashmap() +{ + let data : Vec< HashMap< String, String > > = vec! + [ + { + let mut map = HashMap::new(); + map.insert( "id".to_string(), "1".to_string() ); + map.insert( "created_at".to_string(), "1627845583".to_string() ); + map.insert( "file_ids".to_string(), "[ file1, file2 ]".to_string() ); + map.insert( "tools".to_string(), "".to_string() ); + map + }, + { + let mut map = HashMap::new(); + map.insert( "id".to_string(), "2".to_string() ); + map.insert( "created_at".to_string(), "13".to_string() ); + map.insert( "file_ids".to_string(), "[ file3, file4 ]".to_string() ); + map.insert( "tools".to_string(), "tool1".to_string() ); + map + }, + ]; + + use the_module::Fields; + + use std::borrow::Cow; + + // let _ = as Fields>>>::fields(&map); + + use the_module::TableFormatter; + let _as_table : AsTable< '_, Vec< HashMap< String, String > >, &str, HashMap< String, String >, str> = AsTable::new( &data ); + + /* + let as_table = AsTable::new( &data ); + + let rows = TableRows::rows( &as_table ); + assert_eq!( rows.len(), 2 ); + + let mut output = String::new(); + let mut context = the_module::print::Context::new( &mut output, Default::default() ); + + let _got = the_module::TableFormatter::fmt( &as_table, &mut context ); + + let got = as_table.table_to_string(); + + assert!( got.contains( "│ id │ created_at │ file_ids │ tools │" ) ); + assert!( got.contains( "│ 13 │ [ │ [ │" ) ); + assert!( got.contains( "│ 1627845583 │ [ │ │" ) ); + */ +} + +#[ test ] +fn vec_of_hashmap_str() +{ + let data : Vec< HashMap< &str, String > > = vec! + [ + { + let mut map = HashMap::new(); + map.insert( "id", "1".to_string() ); + map.insert( "created_at", "1627845583".to_string() ); + map.insert( "file_ids", "[ file1, file2 ]".to_string() ); + map.insert( "tools", "".to_string() ); + map + }, + { + let mut map = HashMap::new(); + map.insert( "id", "2".to_string() ); + map.insert( "created_at", "13".to_string() ); + map.insert( "file_ids", "[ file3, file4 ]".to_string() ); + map.insert( "tools", "tool1".to_string() ); + map + }, + ]; + + use the_module::Fields; + + use std::borrow::Cow; + + // let _ = as Fields>>>::fields(&map); + + use the_module::TableFormatter; + //let _as_table : AsTable< '_, Vec< HashMap< &str, String > >, &str, HashMap< &str, String >, str> = AsTable::new( &data ); + + /* + let as_table = AsTable::new( &data ); + + let rows = TableRows::rows( &as_table ); + assert_eq!( rows.len(), 2 ); + + let mut output = String::new(); + let mut context = the_module::print::Context::new( &mut output, Default::default() ); + + let _got = the_module::TableFormatter::fmt( &as_table, &mut context ); + + let got = as_table.table_to_string(); + + assert!( got.contains( "│ id │ created_at │ file_ids │ tools │" ) ); + assert!( got.contains( "│ 13 │ [ │ [ │" ) ); + assert!( got.contains( "│ 1627845583 │ [ │ │" ) ); + */ +} \ No newline at end of file From 47c7543d0f32c83aa94fa2e9221925dc55b5ed3b Mon Sep 17 00:00:00 2001 From: InAnYan Date: Wed, 20 Nov 2024 10:52:16 +0200 Subject: [PATCH 3/5] Add test and fix bug in `extract` --- module/core/format_tools/src/format/print.rs | 13 +++- module/core/format_tools/src/format/table.rs | 17 +++-- .../format_tools/tests/inc/collection_test.rs | 69 ++----------------- 3 files changed, 28 insertions(+), 71 deletions(-) diff --git a/module/core/format_tools/src/format/print.rs b/module/core/format_tools/src/format/print.rs index f3c5d2acc6..6879d8d0ca 100644 --- a/module/core/format_tools/src/format/print.rs +++ b/module/core/format_tools/src/format/print.rs @@ -413,7 +413,13 @@ mod private let mut ncol = 0; let mut ncol_vis = 0; - let fields : Vec< ( Cow< 't, str >, [ usize ; 2 ] ) > = row_iter + // This type stores these data: + // index cell data size of cell + // of the column + // + // We have to store index of the column in order to NOT rely on order of the + // `Cells::cells`. + let mut fields : Vec< ( usize, Cow< 't, str >, [ usize ; 2 ] ) > = row_iter .filter_map ( | ( key, val ) | @@ -459,11 +465,14 @@ mod private }); row.height = row.height.max( sz[ 1 ] ); - return Some( ( val, sz ) ); + return Some( ( key_to_ikey[ key ], val, sz ) ); } ) .collect(); + fields.sort_by( | ( i1, _, _ ), ( i2, _, _ ) | i1.cmp( i2 ) ); + let fields : Vec< ( Cow< 't, str >, [ usize ; 2 ] ) > = fields.into_iter().map( | ( _, k, v ) | ( k, v ) ).collect(); + mcells[ 0 ] = mcells[ 0 ].max( ncol ); mcells_vis[ 0 ] = mcells_vis[ 0 ].max( ncol_vis ); diff --git a/module/core/format_tools/src/format/table.rs b/module/core/format_tools/src/format/table.rs index 6be2d185ca..1fab2ab744 100644 --- a/module/core/format_tools/src/format/table.rs +++ b/module/core/format_tools/src/format/table.rs @@ -79,9 +79,6 @@ mod private /// Marker trait to tag structures for which table trait deducing should be done from trait Fields, which is reflection. pub trait TableWithFields {} - impl TableWithFields for HashMap< String, String > {} - impl TableWithFields for HashMap< &str, String > {} - // = /// A trait for iterating over all cells of a row. @@ -99,6 +96,16 @@ mod private ; } + impl Cells< str > for HashMap< String, String > + { + fn cells< 'a, 'b >( &'a self ) -> impl IteratorTrait< Item = ( &'b str, Option< Cow< 'b, str > > ) > + where + 'a : 'b, + { + self.iter().map( | ( k, v ) | ( k.as_str(), Some( Cow::from( v ) ) ) ) + } + } + impl< Row, CellKey > Cells< CellKey > for Row where @@ -195,7 +202,7 @@ mod private > + 'k + 'v, RowKey : table::RowKey, - Row : TableWithFields + Cells< CellKey >, + Row : Cells< CellKey >, CellKey : table::CellKey + ?Sized, // CellRepr : table::CellRepr, { @@ -271,7 +278,7 @@ mod private where Self : TableRows< RowKey = RowKey, Row = Row, CellKey = CellKey >, RowKey : table::RowKey, - Row : TableWithFields + Cells< CellKey >, + Row : Cells< CellKey >, CellKey : table::CellKey + ?Sized, // CellRepr : table::CellRepr, { diff --git a/module/core/format_tools/tests/inc/collection_test.rs b/module/core/format_tools/tests/inc/collection_test.rs index 59d4d9e5e1..0d066004e2 100644 --- a/module/core/format_tools/tests/inc/collection_test.rs +++ b/module/core/format_tools/tests/inc/collection_test.rs @@ -411,30 +411,21 @@ fn vec_of_hashmap() let mut map = HashMap::new(); map.insert( "id".to_string(), "1".to_string() ); map.insert( "created_at".to_string(), "1627845583".to_string() ); - map.insert( "file_ids".to_string(), "[ file1, file2 ]".to_string() ); - map.insert( "tools".to_string(), "".to_string() ); map }, { let mut map = HashMap::new(); map.insert( "id".to_string(), "2".to_string() ); map.insert( "created_at".to_string(), "13".to_string() ); - map.insert( "file_ids".to_string(), "[ file3, file4 ]".to_string() ); - map.insert( "tools".to_string(), "tool1".to_string() ); map }, ]; - use the_module::Fields; - use std::borrow::Cow; - // let _ = as Fields>>>::fields(&map); - use the_module::TableFormatter; - let _as_table : AsTable< '_, Vec< HashMap< String, String > >, &str, HashMap< String, String >, str> = AsTable::new( &data ); - /* + let _as_table : AsTable< '_, Vec< HashMap< String, String > >, &str, HashMap< String, String >, str> = AsTable::new( &data ); let as_table = AsTable::new( &data ); let rows = TableRows::rows( &as_table ); @@ -447,59 +438,9 @@ fn vec_of_hashmap() let got = as_table.table_to_string(); - assert!( got.contains( "│ id │ created_at │ file_ids │ tools │" ) ); - assert!( got.contains( "│ 13 │ [ │ [ │" ) ); - assert!( got.contains( "│ 1627845583 │ [ │ │" ) ); - */ -} - -#[ test ] -fn vec_of_hashmap_str() -{ - let data : Vec< HashMap< &str, String > > = vec! - [ - { - let mut map = HashMap::new(); - map.insert( "id", "1".to_string() ); - map.insert( "created_at", "1627845583".to_string() ); - map.insert( "file_ids", "[ file1, file2 ]".to_string() ); - map.insert( "tools", "".to_string() ); - map - }, - { - let mut map = HashMap::new(); - map.insert( "id", "2".to_string() ); - map.insert( "created_at", "13".to_string() ); - map.insert( "file_ids", "[ file3, file4 ]".to_string() ); - map.insert( "tools", "tool1".to_string() ); - map - }, - ]; - - use the_module::Fields; - - use std::borrow::Cow; - - // let _ = as Fields>>>::fields(&map); - - use the_module::TableFormatter; - //let _as_table : AsTable< '_, Vec< HashMap< &str, String > >, &str, HashMap< &str, String >, str> = AsTable::new( &data ); - - /* - let as_table = AsTable::new( &data ); - - let rows = TableRows::rows( &as_table ); - assert_eq!( rows.len(), 2 ); + println!("{}", got); - let mut output = String::new(); - let mut context = the_module::print::Context::new( &mut output, Default::default() ); - - let _got = the_module::TableFormatter::fmt( &as_table, &mut context ); - - let got = as_table.table_to_string(); - - assert!( got.contains( "│ id │ created_at │ file_ids │ tools │" ) ); - assert!( got.contains( "│ 13 │ [ │ [ │" ) ); - assert!( got.contains( "│ 1627845583 │ [ │ │" ) ); - */ + assert!( got.contains( "│ id │ created_at │" ) || got.contains( "│ created_at │ id │" ) ); + assert!( got.contains( "│ 1 │ 1627845583 │" ) || got.contains( "│ 1627845583 │ 1 │" ) ); + assert!( got.contains( "│ 2 │ 13 │" ) || got.contains( "│ 13 │ 2 │" ) ); } \ No newline at end of file From 02ed337c2019349556ff2ffef5eaf1214f4f8a24 Mon Sep 17 00:00:00 2001 From: InAnYan Date: Wed, 20 Nov 2024 10:56:11 +0200 Subject: [PATCH 4/5] Fix comment --- module/core/format_tools/src/format/print.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module/core/format_tools/src/format/print.rs b/module/core/format_tools/src/format/print.rs index 6879d8d0ca..248eeb19a8 100644 --- a/module/core/format_tools/src/format/print.rs +++ b/module/core/format_tools/src/format/print.rs @@ -416,10 +416,9 @@ mod private // This type stores these data: // index cell data size of cell // of the column - // + let mut fields : Vec< ( usize, Cow< 't, str >, [ usize ; 2 ] ) > = row_iter // We have to store index of the column in order to NOT rely on order of the // `Cells::cells`. - let mut fields : Vec< ( usize, Cow< 't, str >, [ usize ; 2 ] ) > = row_iter .filter_map ( | ( key, val ) | From 0cb6939fcb1641678b3c1cffc9862d8f14399d08 Mon Sep 17 00:00:00 2001 From: InAnYan Date: Fri, 22 Nov 2024 19:46:31 +0200 Subject: [PATCH 5/5] Fix bug --- module/core/format_tools/src/format/print.rs | 39 +++++++++++--------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/module/core/format_tools/src/format/print.rs b/module/core/format_tools/src/format/print.rs index 77b5b822ee..e102eb5372 100644 --- a/module/core/format_tools/src/format/print.rs +++ b/module/core/format_tools/src/format/print.rs @@ -373,13 +373,26 @@ mod private CellKey : table::CellKey + ?Sized + 'data, // CellRepr : table::CellRepr, { - let rows = table.rows().map( | r | r.cells().map( | ( _, c ) | { - match c + let mut key_to_ikey : HashMap< Cow< 'data, str >, usize > = HashMap::new(); + let mut keys_count = 0; + + let rows = table.rows().map( | r | + { + let mut unsorted : Vec< ( usize, Cow< 'data, str > ) > = r.cells().map( | ( key, c ) | { - Some( c ) => c, - None => Cow::from( "" ), - } - }).collect()).collect(); + if !key_to_ikey.contains_key( key.borrow() ) + { + key_to_ikey.insert( key.borrow().into(), keys_count ); + keys_count += 1; + } + + ( key_to_ikey[ key.borrow() ], c.unwrap_or( Cow::from( "" ) ) ) + } ).collect(); + + unsorted.sort_by( | ( i1, _ ), ( i2, _ ) | i1.cmp(i2) ); + + unsorted.into_iter().map( | ( _, c ) | c).collect() + } ).collect(); let has_header = table.header().is_some(); @@ -446,12 +459,7 @@ mod private let mut ncol = 0; let mut ncol_vis = 0; - // This type stores these data: - // index cell data size of cell - // of the column - let mut fields : Vec< ( usize, Cow< 'data, str >, [ usize ; 2 ] ) > = row_data - // We have to store index of the column in order to NOT rely on order of the - // `Cells::cells`. + let fields : Vec< ( Cow< 'data, str >, [ usize ; 2 ] ) > = row_data .into_iter() .enumerate() .filter_map @@ -500,14 +508,11 @@ mod private }); row.height = row.height.max( sz[ 1 ] ); - return Some( ( key_to_ikey[ key ], val, sz ) ); + return Some( ( val, sz ) ); } ) .collect(); - fields.sort_by( | ( i1, _, _ ), ( i2, _, _ ) | i1.cmp( i2 ) ); - let fields : Vec< ( Cow< 't, str >, [ usize ; 2 ] ) > = fields.into_iter().map( | ( _, k, v ) | ( k, v ) ).collect(); - mcells[ 0 ] = mcells[ 0 ].max( ncol ); mcells_vis[ 0 ] = mcells_vis[ 0 ].max( ncol_vis ); @@ -543,7 +548,7 @@ mod private mchars[ 0 ] = col_descriptors.iter().fold( 0, | acc, col | acc + col.width ); mchars[ 1 ] = row_descriptors.iter().fold( 0, | acc, row | acc + if row.vis { row.height } else { 0 } ); - + let mut x = InputExtract::< '_ > { mcells,