1 unstable release
0.1.0 | Aug 8, 2023 |
---|
#924 in Procedural macros
14KB
299 lines
pprint
A Rust library for pretty ✨ printing using a document model. Automatically derive
Pretty
for structs, enums, and primitive types; vector and map types are also
supported by default; very similar to the derive(Debug)
macro, just prettier and more
configurable.
Usage
use pprint::{Doc, Printer, PRINTER};
let doc = Doc::from(vec![1, 2, 3])
.wrap("[", "]")
.join(", ");
print!("{}", PRINTER.pretty(doc));
// prints:
// [
// 1,
// 2,
// 3
// ]
Document Model
The document model provides a rich set of building blocks:
- Primitive values like strings, numbers
- Containers like vectors, tuples, maps, sets
- Formatting like
concat
,join
,wrap
,group
- Indentation control with
indent
anddedent
- Conditional formatting with
if_break
- Line breaks like
hardline
,softline
The Printer
handles pretty printing a Doc
to a string with configurable options:
max_width
- maximum width of each lineindent
- number of spaces for each indentation levelbreak_long_text
- insert line breaks for long textuse_tabs
- use tabs instead of spaces for indentation
Derive Macro
Half of the library's development time was spent on the derive macro, allowing for easy pretty printing of essentially any type. Here's a trivial example:
#[derive(Pretty)]
struct Point {
x: f64,
y: f64
}
let point = Point { x: 1.0, y: 2.0 };
print!("{}", Doc::from(point)); // prints "(x: 1, y: 2)"
Pretty
supports an additional attribute, pprint
, which is used to customize an
object's pretty printing definition. The following options are available:
- skip: bool: Skip this field - don't include it in the output
- indent: bool: Indent this field - add a newline and indent before and after
- rename: Option: Rename this field - use the given string as the field name
- getter: Option: Use the given function to get the value of this field
- verbose: bool: Verbose output - include field names in output
#[derive(Pretty)]
#[pprint(verbose)]
struct Point {
#[pprint(rename = "x-coordinate")]
x: f64,
#[pprint(rename = "y-coordinate")]
y: f64
#[pprint(skip)]
_skip_me: bool,
}
let point = Point { x: 1.0, y: 2.0, _skip_me: true };
print!("{}", Doc::from(point));
// prints:
// Point {
// x-coordinate: 1,
// y-coordinate: 2
// }
Structures can be arbitrarily nested, & c. & c. More involved examples can be found in the tests file.
Dependencies
~1.5MB
~35K SLoC