Open abhillman opened 1 month ago
Hey @abhillman
So I am sure there are many ways to do that, depending on your needs, but the easiest based on your example is probably the next one.
use json_to_table::{json_to_table, Orientation};
use serde::Serialize;
#[derive(Serialize)]
struct Thing {
f1: String,
f2: String,
f3: String,
}
fn main() {
let t1 = Thing {
f1: "a".to_string(),
f2: "b".to_string(),
f3: "c".to_string(),
};
let t2 = Thing {
f1: "d".to_string(),
f2: "e".to_string(),
f3: "f".to_string(),
};
let t3 = Thing {
f1: "g".to_string(),
f2: "h".to_string(),
f3: "i".to_string(),
};
let data = vec![t1, t2, t3];
let json = serde_json::to_value(data).unwrap();
let table = json_to_table(&json)
.object_orientation(Orientation::Row)
.array_orientation(Orientation::Row)
.into_table();
println!("{}", table)
}
+---------------------+---------------------+---------------------+
| +-----+-----+-----+ | +-----+-----+-----+ | +-----+-----+-----+ |
| | f1 | f2 | f3 | | | f1 | f2 | f3 | | | f1 | f2 | f3 | |
| +-----+-----+-----+ | +-----+-----+-----+ | +-----+-----+-----+ |
| | a | b | c | | | d | e | f | | | g | h | i | |
| +-----+-----+-----+ | +-----+-----+-----+ | +-----+-----+-----+ |
+---------------------+---------------------+---------------------+
Just in case you can customize it for example like this
use json_to_table::{json_to_table, Orientation};
use serde::Serialize;
use tabled::settings::{Padding, Style};
#[derive(Serialize)]
struct Thing {
f1: String,
f2: String,
f3: String,
}
fn main() {
let t1 = Thing {
f1: "a".to_string(),
f2: "b".to_string(),
f3: "c".to_string(),
};
let t2 = Thing {
f1: "d".to_string(),
f2: "e".to_string(),
f3: "f".to_string(),
};
let t3 = Thing {
f1: "g".to_string(),
f2: "h".to_string(),
f3: "i".to_string(),
};
let data = vec![t1, t2, t3];
let json = serde_json::to_value(data).unwrap();
let mut table = json_to_table(&json)
.object_orientation(Orientation::Row)
.array_orientation(Orientation::Row)
.with(Style::modern_rounded())
.into_table();
table.with(Style::modern()).with(Padding::zero());
println!("{}", table)
}
┌───────────────────┬───────────────────┬───────────────────┐
│╭─────┬─────┬─────╮│╭─────┬─────┬─────╮│╭─────┬─────┬─────╮│
││ f1 │ f2 │ f3 │││ f1 │ f2 │ f3 │││ f1 │ f2 │ f3 ││
│├─────┼─────┼─────┤│├─────┼─────┼─────┤│├─────┼─────┼─────┤│
││ a │ b │ c │││ d │ e │ f │││ g │ h │ i ││
│╰─────┴─────┴─────╯│╰─────┴─────┴─────╯│╰─────┴─────┴─────╯│
└───────────────────┴───────────────────┴───────────────────┘
Thanks so much for your reply. Is there a minimal way to do something like the following? Of course, I can definitely hack something together... but:
+---------------------+
| +-----+-----+-----+ |
| | f1 | f2 | f3 | |
| +-----+-----+-----+ |
| | a | b | c | |
| | d | e | f | |
| | g | h | i | |
| +-----+-----+-----+ |
+---------------------+
You're right there plenty (and I mean really a lot) of ways to do that.
Somehow I tried to stick to basic tabled
without use of json_to_table
.
use std::{collections::HashMap, iter::FromIterator};
use tabled::{
builder::Builder,
settings::{
style::{HorizontalLine, On},
Style,
},
};
// well... yes a bit complex but it's case we use CONST
const STYLE: Style<On, On, On, On, (), On, 1, 0> = Style::modern()
.remove_horizontal()
.horizontals([(1, HorizontalLine::inherit(Style::modern()))]);
fn main() {
let json = serde_json::json!(
[
{ "field1": "1" },
{ "field1": "2", "field2": 4 },
{ "field1": "3", "field2": 4 },
{ "field1": "4", "field3": 10 },
]
);
let map = json
.as_array()
.unwrap()
.iter()
.map(|value| value.as_object().unwrap())
.fold(HashMap::new(), |mut acc, row| {
for (key, element) in row {
acc.entry(key.to_string())
.or_insert_with(Vec::new)
.push(element.to_string());
}
acc
});
let mut builder = Builder::from_iter(map.values());
builder.insert_column(0, map.keys());
let builder = builder.index().column(0).transpose();
let mut table = builder.build();
table.with(STYLE);
println!("{}", table);
}
┌────────┬────────┬────────┐
│ field1 │ field2 │ field3 │
├────────┼────────┼────────┤
│ "1" │ 4 │ 10 │
│ "2" │ 4 │ │
│ "3" │ │ │
│ "4" │ │ │
└────────┴────────┴────────┘
But maybe it's common behaivour (I mean your json example and it worth to add some function to json_to_table to parse it right away. )
My example could be done pretty affective if switched to iterative approach rather then collecting a HashMap
.
You could build Builder
step by step.
Also as a different approach there could be usage for PoolTable
and TableValue
.
Results in:
Is there a way to get f1, f2, f3 as the header and values as rows?