Crates.io | debug3 |
lib.rs | debug3 |
version | 0.4.1 |
source | src |
created_at | 2022-04-15 20:57:14.026314 |
updated_at | 2024-01-03 19:18:29.935815 |
description | Space Efficient Pretty Printer |
homepage | |
repository | https://github.com/aDotInTheVoid/debug3/ |
max_upload_size | |
id | 568692 |
size | 7,811,149 |
A space effiecent replacement for [std::fmt::Debug
]
Lets say you have data that looks like this:
let complex_structure = vec![
vec![None, Some(2)],
vec![Some(2), None],
vec![Some(4), Some(777)],
vec![None, Some(2)],
vec![Some(2), None],
vec![None, None, None, None, None],
];
And you want to format it as a string. You could use format!("{:?}", complex_structure)
and get something like
[[None, Some(2)], [Some(2), None], [Some(4), Some(777)], [None, Some(2)], [Some(2), None], [None, None, None, None, None]]
But this is too much one one line, and is hard to read. And it gets worse for larger structures.
Fortunaly theirs an alternative format!("{:#?}", complex_structure)
, which gives
[
[
None,
Some(
2,
),
],
[
Some(
2,
),
None,
],
[
Some(
4,
),
Some(
777,
),
],
[
None,
Some(
2,
),
],
[
Some(
2,
),
None,
],
[
None,
None,
None,
None,
None,
],
]
This has the oposite problem, where it uses too much space, even when the code could be packed denser.
debug3
provides a third option that is denser than :#?
but more readable than :?
. If you use debug3::pprint(complex_structure)
, you get
[
[None, Some(2)],
[Some(2), None],
[Some(4), Some(777)],
[None, Some(2)],
[Some(2), None],
[None, None, None, None, None],
]
The main entrypoint is the [Debug
] trait, which is the equivalent to [std::fmt::Debug
], and has a similar API.
This can be either #[derive]
d, or implemented manually.
use debug3::{Debug, Formatter, pprint};
#[derive(Debug)]
struct MyStruct {
a: i32,
b: i32,
}
struct AnotherStruct {
a: i32,
b: i32,
}
impl Debug for AnotherStruct {
fn fmt(&self, f: &mut Formatter) {
f.debug_struct("AnotherStruct")
.field("a", &self.a)
.field("b", &self.b)
.finish()
}
}
assert_eq!(pprint(MyStruct { a: 1, b: 2 }), "MyStruct { a: 1, b: 2 }");
assert_eq!(pprint(AnotherStruct { a: 1, b: 2 }), "AnotherStruct { a: 1, b: 2 }");
Once your type implements [Debug
], you have several options to format it
pprint
]: Convert it to a [String
]dbg
]: Print it to stderrstd::fmt::Debug
:While the main advantage of debug3
is the superior output quality, it has several drawbacks compared to [std::fmt
] that you should know
std::fmt::Debug
],
vitrualy no types outside of [std
] implement [debug3::Debug
][Debug
].std::fmt
] is also availible as [core::fmt
], which allows
you to use it in no_std
environments. debug3
requires several allocated
data structures, so cannot support these environments.std::fmt::Formatter
] has many more API's for implementing
[std::fmt::Debug
]. In order to achive nice formatting, we cannot accept
arbitrary strings, but must have items in the form of Structs, Tuples, Maps,
Lists and Sets.format!("{:x?}, 1)
to configure
how numbers are printed.std::format
] to easily create a
string from several elements which implement [Debug
]debug3
would not be possible without all of the following excelent work
core::fmt
- The public API of [Formatter
] and [builders]
prettyplease
- Most of the prety printing algorithm is lifted directly from this crate
custom_debug
- The derive macro for [Debug
] is based on this crate.
python's pprint
- Inspiration for this type of formatting for debug output.