Comments (9)
Good idea.
Will you open a PR?
I am confident somebody who is good with macros could improve this 2x
Well here's not 2x but I think a bit better.
( $($table:expr), *; $N:expr) => {{
let groupings = &[$($table.to_string(),)*];
let groups = groupings
.chunks($N)
.map(|chunk| {
chunk.iter()
.map(ToString::to_string)
.chain(std::iter::repeat(String::default()))
.take($N)
});
let mut builder = tabled::builder::Builder::default();
// todo: (yet not merged) builder.hint_size($N);
for group in groups {
builder.add_record(group);
}
builder.build()
}};
from tabled.
🙋🏻♂️
If this ticket is still available I'd like to draft a solution or two for you 😃
from tabled.
Hello @IsaacCloos, feel free to try it.
Remember that rows in some tables might be multiline.
I am also thinking how would Width
be applied to this type.
But it's specifics and it may not be as it's done in ExpandedDisplay
.
PS: The code base was changed quite a bit from your last look I guess. I think its better but if you have any question ping me.
from tabled.
I actually very suprised how you managed it.
I mean such an idea didn't came to my mind.
I was always picturing it to be done as a different type which would probably have some unique methods (which I am not sure what they are).
Very elegant solution.
Notes:
-
We could use tuple instead of a new type
TableGroup
. Not sure which is better but in your case we have a type check. In tuple case any fmt::Display will work.macro_rules! parallel { ( $($table:expr),* ) => {{ Table::new([( $($table.to_string(),)*) ]) .with(Style::empty()) .with(Extract::rows(1..)) }}; }
-
I think
Extract
call is less efficient than thislet mut b = Table::builder([TableGroup($($table,)*)]); b.remove_columns(); b.build().with(Style::empty())
-
It could be cool to be able to use
&Table
in input.parallel!(&table_a, &table_b)
-
I would not change a default Style to act as default
Table::new
.
I am thinking is there any options we could provide to the macros?
Do you have any ideas?
from tabled.
I am thinking if parallel![table; 4]
would be any useful, if it would behave as vec![table; 4]
from tabled.
Also I am thinking if it must be a macro actually.
At your initial code it must has been.
But if you'll look at mine example there's nothing there which stopes it being a function.
from tabled.
Hello, I have a draft of a lightweight enhancement for this feature.
This is the first time I've written macros so please don't hold back on criticism.
Feedback makes a HUGE difference for me 😄
macro code:
macro_rules! replace_expr {
($_t:tt $sub:ty) => {
$sub
};
}
macro_rules! group_builder {
( $($typ:ty),* ) => {
#[derive(Tabled)]
struct TableGroup($($typ,)*);
}
}
macro_rules! parallel {
( $($table:expr),* ) => {{
group_builder!( $(
replace_expr!(
($table)
Table
)
),*);
Table::new([TableGroup($($table,)*)])
.with(Style::empty())
.with(Extract::rows(1..))
}};
}
full example file found here for you to run and review
the following are my opinions on this solution:
pros
- utilizes existing apis to deliver the desired result. minimal code bloat
- highly flexible. max number of parallel tables is governed by the recursion_limit
- leverages the powerful nested tables feature to prevent side-by-side tables from conflicting each-others styles
- idea could be expanded to a more general tool to group tables. this could improve the ergonomics of creating nested tables
cons
- general macro trade offs (longer compile times, ext)
- solution exists outside the core codebase and could easily be disrupted by changes to several different apis
- to me it feels a bit 'hacky' to assemble new tables 'invisibly', but I do like the ergonomics of easily making side-by-side displays like this
Again, your feedback means a lot to me. If you are interested in this kind of approach I can clean it up and make a proper PR with tests, example, documentation, the usual 👍🏻
from tabled.
Great feedback 🤩
I learned a LOT about Rust and Tabled
from this issue so far 👍🏻
New proposal (with your feedback)
macro_rules! parallel {
( $($table:expr), * ) => {{
let mut builder = Table::builder([( $($table.to_string(),)*) ]);
builder.remove_columns();
builder.build()
}};
}
Achieves original ticket goal with minimal code complexity and 0 refactoring necessary 👍🏻
Rough Draft of extending concept
I am thinking is there any options we could provide to the macros?
Do you have any ideas?
macro_rules! parallel_plus {
( $($table:expr), * ) => {{
let mut builder = Table::builder([( $($table.to_string(),)*) ]);
builder.remove_columns();
builder.build()
}};
( $($table:expr), *; $N:expr) => {{
let groupings = vec![$($table.to_string(),)*];
let groups = groupings.chunks($N);
let mapped = groups.map(|chunk| {
let mut tables = chunk.iter().map(ToString::to_string);
(
$(
replace_expr!(
($table)
tables.next().unwrap_or_default()
)
),*
)
});
let mut builder = Table::builder(mapped);
builder.remove_columns();
builder.build().with(Extract::columns(..$N))
}};
}
I am confident somebody who is good with macros could improve this 2x. However, I was able to get this working to give some nice extra functionality of defining how the tables are divided between rows.
This allows for the following:
parallel_plus!(table_a, table_b, table_c, table_a; 3)
+--------------------------------+---------------------------------------------+-------------------------------------------+
| | name | age | is_validated | | ┌────────────────────┬─────┬──────────────┐ | .---------------------------------------. |
| |-------|-----|--------------| | │ name │ age │ is_validated │ | | name | age | is_validated | |
| | Sam | 31 | true | | ├────────────────────┼─────┼──────────────┤ | | Jon Doe | 255 | false | |
| | Sarah | 26 | true | | │ Jack Black │ 51 │ false │ | | Mark Nelson | 13 | true | |
| | ├────────────────────┼─────┼──────────────┤ | | Terminal Monitor | 0 | false | |
| | │ Michelle Goldstein │ 44 │ true │ | | Adam Blend | 17 | true | |
| | └────────────────────┴─────┴──────────────┘ | '---------------------------------------' |
+--------------------------------+---------------------------------------------+-------------------------------------------+
| | name | age | is_validated | | | |
| |-------|-----|--------------| | | |
| | Sam | 31 | true | | | |
| | Sarah | 26 | true | | | |
+--------------------------------+---------------------------------------------+-------------------------------------------+
parallel_plus!(table_a, table_b, table_c, table_a; 2)
+-------------------------------------------+---------------------------------------------+
| | name | age | is_validated | | ┌────────────────────┬─────┬──────────────┐ |
| |-------|-----|--------------| | │ name │ age │ is_validated │ |
| | Sam | 31 | true | | ├────────────────────┼─────┼──────────────┤ |
| | Sarah | 26 | true | | │ Jack Black │ 51 │ false │ |
| | ├────────────────────┼─────┼──────────────┤ |
| | │ Michelle Goldstein │ 44 │ true │ |
| | └────────────────────┴─────┴──────────────┘ |
+-------------------------------------------+---------------------------------------------+
| .---------------------------------------. | | name | age | is_validated | |
| | name | age | is_validated | | |-------|-----|--------------| |
| | Jon Doe | 255 | false | | | Sam | 31 | true | |
| | Mark Nelson | 13 | true | | | Sarah | 26 | true | |
| | Terminal Monitor | 0 | false | | |
| | Adam Blend | 17 | true | | |
| '---------------------------------------' | |
+-------------------------------------------+---------------------------------------------+
parallel_plus!(table_a, table_b, table_c, table_a; 1)
+---------------------------------------------+
| | name | age | is_validated | |
| |-------|-----|--------------| |
| | Sam | 31 | true | |
| | Sarah | 26 | true | |
+---------------------------------------------+
| ┌────────────────────┬─────┬──────────────┐ |
| │ name │ age │ is_validated │ |
| ├────────────────────┼─────┼──────────────┤ |
| │ Jack Black │ 51 │ false │ |
| ├────────────────────┼─────┼──────────────┤ |
| │ Michelle Goldstein │ 44 │ true │ |
| └────────────────────┴─────┴──────────────┘ |
+---------------------------------------------+
| .---------------------------------------. |
| | name | age | is_validated | |
| | Jon Doe | 255 | false | |
| | Mark Nelson | 13 | true | |
| | Terminal Monitor | 0 | false | |
| | Adam Blend | 17 | true | |
| '---------------------------------------' |
+---------------------------------------------+
| | name | age | is_validated | |
| |-------|-----|--------------| |
| | Sam | 31 | true | |
| | Sarah | 26 | true | |
+---------------------------------------------+
Thoughts?
from tabled.
I am a fan of the test_table! macro 😄
Easier to use than manual. Cleaner. More clear 👍🏻
from tabled.
Related Issues (20)
- Unicode width not being accounted for HOT 2
- Can it be integrated with leptos? Can you give an example? HOT 4
- Add per column alignment setting for `ColumnNames`
- Typo in lib.rs line 72 - "almoust" should be "almost" HOT 1
- Is there any way to cut short long row entries HOT 3
- reduce padding option?
- Possible way to set intersection to a different character for just one row/column? HOT 3
- Make all set functions for `Style` `const` HOT 1
- `table.is_empty()` on tables with only a header row HOT 3
- Question: Is there a way to conditionally apply a cell background color? HOT 5
- Impossible to call `Style::empty().remove_left()` HOT 8
- `Rotate::Bottom` must reorder rows?
- Refactor `Builder` methods HOT 17
- Add a indent size
- Does not build on MacOS HOT 4
- Add a benchmark to compare against a basic tabulation HOT 1
- Why the left/right border does not have intersection `CompactTable`
- Impl `Dimension` for Vec<usize>
- Add a `skip` function to `CompactTable`
- Create a iterative interface to `CompactTable`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tabled.