Expand description
Representing data to the user (i.e. in CLI or TUI) usually requires converting data into vector
of vector of strings with the data. Further this data is being passed to tools like
comfy_table
, cli-table
or similar. Preparing such data is a tedious job. This is where
StructTable is coming to help.
For a structure like:
use serde::Serialize;
use serde_json::Value;
use structable::{StructTable, StructTableOptions};
#[derive(Serialize, StructTable)]
struct User {
#[structable(title = "ID")]
id: u64,
first_name: String,
last_name: String,
#[structable(title = "Long", wide)]
extra: String,
#[structable(optional, serialize, wide)]
complex_data: Option<Value>,
#[structable(optional)]
dummy: Option<String>,
}
What you get is:
impl StructTable for User {
fn class_headers<O: StructTableOptions>(
options: &O,
) -> Option<Vec<String>> {
let mut headers: Vec<String> = Vec::new();
if options.should_return_field("ID", false) {
headers.push("ID".to_string());
}
if options.should_return_field("first_name", false) {
headers.push("first_name".to_string());
}
if options.should_return_field("last_name", false) {
headers.push("last_name".to_string());
}
if options.should_return_field("Long", true) {
headers.push("Long".to_string());
}
if options.should_return_field("complex_data", true) {
headers.push("complex_data".to_string());
}
if options.should_return_field("dummy", false) {
headers.push("dummy".to_string());
}
Some(headers)
}
fn data<O: StructTableOptions>(
&self,
options: &O,
) -> ::std::vec::Vec<Option<::std::string::String>> {
let mut row: Vec<Option<String>> = Vec::new();
if options.should_return_field("ID", false) {
row.push(Some(self.id.to_string()));
}
if options.should_return_field("first_name", false) {
row.push(Some(self.first_name.to_string()));
}
if options.should_return_field("last_name", false) {
row.push(Some(self.last_name.to_string()));
}
if options.should_return_field("Long", true) {
row.push(Some(self.extra.to_string()));
}
if options.should_return_field("complex_data", true) {
row.push(
self
.complex_data
.clone()
.map(|v| {
if options.pretty_mode() {
serde_json::to_string_pretty(&v)
} else {
serde_json::to_string(&v)
}
.unwrap_or_else(|_| String::from(
"<ERROR SERIALIZING DATA>",
))
}),
);
}
if options.should_return_field("dummy", false) {
row.push(self.dummy.clone().map(|x| x.to_string()));
}
row
}
fn status(&self) -> Option<String> {
None
}
}
§Field parameters
-
title
column name to be returned. When unset field name is used. -
wide
return field only in thewide
mode, or when explicitly requested throughfields
-
serialize
serialize field value to the json. Whenpretty
mode is requested usesto_pretty_string()
§Example
use structable::{build_table, build_list_table};
use structable::{OutputConfig, StructTable, StructTableOptions};
#[derive(Serialize, StructTable)]
struct User {
#[structable(title = "ID")]
id: u64,
first_name: &'static str,
last_name: &'static str,
#[structable(title = "Long(only in wide mode)", wide)]
extra: &'static str,
#[structable(optional, pretty)]
complex_data: Option<Value>
}
let users = vec![
User {
id: 1,
first_name: "Scooby",
last_name: "Doo",
extra: "Foo",
complex_data: Some(json!({"a": "b", "c": "d"}))
},
User {
id: 2,
first_name: "John",
last_name: "Cena",
extra: "Bar",
complex_data: None
},
];
let user = User {
id: 1,
first_name: "Scooby",
last_name: "Doo",
extra: "XYZ",
complex_data: Some(json!({"a": "b", "c": "d"}))
};
let config = OutputConfig {
fields: BTreeSet::from(["Last Name".to_string()]),
wide: false,
pretty: false
};
let data = build_table(&user, &config);
println!("Single user {:?} => {:?}", data.0, data.1);
let data2 = build_list_table(users.iter(), &config);
println!("multiple users {:?} => {:?}", data2.0, data2.1);
Single user ["Attribute", "Value"] => [["id", "1"], ["first_name", "Scooby"], ["last_name", "Doo"], ["long_only", "XYZ"]]
multiple user ["id", "first_name", "last_name", "long_only"] => [["1", "Scooby", "Doo", "Foo"], ["2", "John", "Cena", "Bar"]]
Structs§
- Output
Config - Output configuration
Traits§
- Struct
Table - Trait for building tables out of structures
- Struct
Table Options - StructTable output configuration trait
Functions§
- build_
list_ table - Build a table for list of entries
- build_
table - Build a table for a single structure
Derive Macros§
- Struct
Table - Derive macro to implement
StructTable
trait