rust/library/core/tests/fmt/builders.rs
Trevor Gross 827970ebe9 Implement debug_more_non_exhaustive
Add a `.finish_non_exhaustive()` method to `DebugTuple`, `DebugSet`,
`DebugList`, and `DebugMap`. This indicates that the structures have
remaining items with `..`.

This implements the ACP at
<https://github.com/rust-lang/libs-team/issues/248>.
2024-07-21 12:05:02 -05:00

1045 lines
24 KiB
Rust

mod debug_struct {
use std::fmt;
#[test]
fn test_empty() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Foo").finish()
}
}
assert_eq!("Foo", format!("{Foo:?}"));
assert_eq!("Foo", format!("{Foo:#?}"));
}
#[test]
fn test_single() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Foo").field("bar", &true).finish()
}
}
assert_eq!("Foo { bar: true }", format!("{Foo:?}"));
assert_eq!(
"Foo {
bar: true,
}",
format!("{Foo:#?}")
);
}
#[test]
fn test_multiple() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Foo")
.field("bar", &true)
.field("baz", &format_args!("{}/{}", 10, 20))
.finish()
}
}
assert_eq!("Foo { bar: true, baz: 10/20 }", format!("{Foo:?}"));
assert_eq!(
"Foo {
bar: true,
baz: 10/20,
}",
format!("{Foo:#?}")
);
}
#[test]
fn test_nested() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Foo")
.field("bar", &true)
.field("baz", &format_args!("{}/{}", 10, 20))
.finish()
}
}
struct Bar;
impl fmt::Debug for Bar {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Bar").field("foo", &Foo).field("hello", &"world").finish()
}
}
assert_eq!(
r#"Bar { foo: Foo { bar: true, baz: 10/20 }, hello: "world" }"#,
format!("{Bar:?}")
);
assert_eq!(
r#"Bar {
foo: Foo {
bar: true,
baz: 10/20,
},
hello: "world",
}"#,
format!("{Bar:#?}")
);
}
#[test]
fn test_empty_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Foo").finish_non_exhaustive()
}
}
assert_eq!("Foo { .. }", format!("{Foo:?}"));
assert_eq!("Foo { .. }", format!("{Foo:#?}"));
}
#[test]
fn test_multiple_and_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Foo")
.field("bar", &true)
.field("baz", &format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
assert_eq!("Foo { bar: true, baz: 10/20, .. }", format!("{Foo:?}"));
assert_eq!(
"Foo {
bar: true,
baz: 10/20,
..
}",
format!("{Foo:#?}")
);
}
#[test]
fn test_nested_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Foo")
.field("bar", &true)
.field("baz", &format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
struct Bar;
impl fmt::Debug for Bar {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Bar")
.field("foo", &Foo)
.field("hello", &"world")
.finish_non_exhaustive()
}
}
assert_eq!(
r#"Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: "world", .. }"#,
format!("{Bar:?}")
);
assert_eq!(
r#"Bar {
foo: Foo {
bar: true,
baz: 10/20,
..
},
hello: "world",
..
}"#,
format!("{Bar:#?}")
);
}
}
mod debug_tuple {
use std::fmt;
#[test]
fn test_empty() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Foo").finish()
}
}
assert_eq!("Foo", format!("{Foo:?}"));
assert_eq!("Foo", format!("{Foo:#?}"));
}
#[test]
fn test_single() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Foo").field(&true).finish()
}
}
assert_eq!("Foo(true)", format!("{Foo:?}"));
assert_eq!(
"Foo(
true,
)",
format!("{Foo:#?}")
);
}
#[test]
fn test_multiple() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Foo").field(&true).field(&format_args!("{}/{}", 10, 20)).finish()
}
}
assert_eq!("Foo(true, 10/20)", format!("{Foo:?}"));
assert_eq!(
"Foo(
true,
10/20,
)",
format!("{Foo:#?}")
);
}
#[test]
fn test_nested() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Foo").field(&true).field(&format_args!("{}/{}", 10, 20)).finish()
}
}
struct Bar;
impl fmt::Debug for Bar {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Bar").field(&Foo).field(&"world").finish()
}
}
assert_eq!(r#"Bar(Foo(true, 10/20), "world")"#, format!("{Bar:?}"));
assert_eq!(
r#"Bar(
Foo(
true,
10/20,
),
"world",
)"#,
format!("{Bar:#?}")
);
}
#[test]
fn test_empty_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Foo").finish_non_exhaustive()
}
}
assert_eq!("Foo(..)", format!("{Foo:?}"));
assert_eq!("Foo(..)", format!("{Foo:#?}"));
}
#[test]
fn test_multiple_and_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Foo")
.field(&true)
.field(&format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
assert_eq!("Foo(true, 10/20, ..)", format!("{Foo:?}"));
assert_eq!(
"Foo(
true,
10/20,
..
)",
format!("{Foo:#?}")
);
}
#[test]
fn test_nested_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Foo")
.field(&true)
.field(&format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
struct Bar;
impl fmt::Debug for Bar {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("Bar").field(&Foo).field(&"world").finish_non_exhaustive()
}
}
assert_eq!(r#"Bar(Foo(true, 10/20, ..), "world", ..)"#, format!("{Bar:?}"));
assert_eq!(
r#"Bar(
Foo(
true,
10/20,
..
),
"world",
..
)"#,
format!("{Bar:#?}")
);
}
}
mod debug_map {
use std::fmt;
#[test]
fn test_empty() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map().finish()
}
}
assert_eq!("{}", format!("{Foo:?}"));
assert_eq!("{}", format!("{Foo:#?}"));
}
#[test]
fn test_single() {
struct Entry;
impl fmt::Debug for Entry {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map().entry(&"bar", &true).finish()
}
}
struct KeyValue;
impl fmt::Debug for KeyValue {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map().key(&"bar").value(&true).finish()
}
}
assert_eq!(format!("{Entry:?}"), format!("{KeyValue:?}"));
assert_eq!(format!("{Entry:#?}"), format!("{KeyValue:#?}"));
assert_eq!(r#"{"bar": true}"#, format!("{Entry:?}"));
assert_eq!(
r#"{
"bar": true,
}"#,
format!("{Entry:#?}")
);
}
#[test]
fn test_multiple() {
struct Entry;
impl fmt::Debug for Entry {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map()
.entry(&"bar", &true)
.entry(&10, &format_args!("{}/{}", 10, 20))
.finish()
}
}
struct KeyValue;
impl fmt::Debug for KeyValue {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map()
.key(&"bar")
.value(&true)
.key(&10)
.value(&format_args!("{}/{}", 10, 20))
.finish()
}
}
assert_eq!(format!("{Entry:?}"), format!("{KeyValue:?}"));
assert_eq!(format!("{Entry:#?}"), format!("{KeyValue:#?}"));
assert_eq!(r#"{"bar": true, 10: 10/20}"#, format!("{Entry:?}"));
assert_eq!(
r#"{
"bar": true,
10: 10/20,
}"#,
format!("{Entry:#?}")
);
}
#[test]
fn test_nested() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map()
.entry(&"bar", &true)
.entry(&10, &format_args!("{}/{}", 10, 20))
.finish()
}
}
struct Bar;
impl fmt::Debug for Bar {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map().entry(&"foo", &Foo).entry(&Foo, &"world").finish()
}
}
assert_eq!(
r#"{"foo": {"bar": true, 10: 10/20}, {"bar": true, 10: 10/20}: "world"}"#,
format!("{Bar:?}")
);
assert_eq!(
r#"{
"foo": {
"bar": true,
10: 10/20,
},
{
"bar": true,
10: 10/20,
}: "world",
}"#,
format!("{Bar:#?}")
);
}
#[test]
fn test_entry_err() {
// Ensure errors in a map entry don't trigger panics (#65231)
use std::fmt::Write;
struct ErrorFmt;
impl fmt::Debug for ErrorFmt {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
Err(fmt::Error)
}
}
struct KeyValue<K, V>(usize, K, V);
impl<K, V> fmt::Debug for KeyValue<K, V>
where
K: fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut map = fmt.debug_map();
for _ in 0..self.0 {
map.entry(&self.1, &self.2);
}
map.finish()
}
}
let mut buf = String::new();
assert!(write!(&mut buf, "{:?}", KeyValue(1, ErrorFmt, "bar")).is_err());
assert!(write!(&mut buf, "{:?}", KeyValue(1, "foo", ErrorFmt)).is_err());
assert!(write!(&mut buf, "{:?}", KeyValue(2, ErrorFmt, "bar")).is_err());
assert!(write!(&mut buf, "{:?}", KeyValue(2, "foo", ErrorFmt)).is_err());
}
#[test]
#[should_panic]
fn test_invalid_key_when_entry_is_incomplete() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map().key(&"bar").key(&"invalid").finish()
}
}
let _ = format!("{Foo:?}");
}
#[test]
#[should_panic]
fn test_invalid_finish_incomplete_entry() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map().key(&"bar").finish()
}
}
let _ = format!("{Foo:?}");
}
#[test]
#[should_panic]
fn test_invalid_value_before_key() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map().value(&"invalid").key(&"bar").finish()
}
}
let _ = format!("{Foo:?}");
}
#[test]
fn test_empty_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map().finish_non_exhaustive()
}
}
assert_eq!("{..}", format!("{Foo:?}"));
assert_eq!("{..}", format!("{Foo:#?}"));
}
#[test]
fn test_multiple_and_non_exhaustive() {
struct Entry;
impl fmt::Debug for Entry {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map()
.entry(&"bar", &true)
.entry(&10, &format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
struct KeyValue;
impl fmt::Debug for KeyValue {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map()
.key(&"bar")
.value(&true)
.key(&10)
.value(&format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
assert_eq!(format!("{Entry:?}"), format!("{KeyValue:?}"));
assert_eq!(format!("{Entry:#?}"), format!("{KeyValue:#?}"));
assert_eq!(r#"{"bar": true, 10: 10/20, ..}"#, format!("{Entry:?}"));
assert_eq!(
r#"{
"bar": true,
10: 10/20,
..
}"#,
format!("{Entry:#?}")
);
}
#[test]
fn test_nested_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map()
.entry(&"bar", &true)
.entry(&10, &format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
struct Bar;
impl fmt::Debug for Bar {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_map().entry(&"foo", &Foo).entry(&Foo, &"world").finish_non_exhaustive()
}
}
assert_eq!(
r#"{"foo": {"bar": true, 10: 10/20, ..}, {"bar": true, 10: 10/20, ..}: "world", ..}"#,
format!("{Bar:?}")
);
assert_eq!(
r#"{
"foo": {
"bar": true,
10: 10/20,
..
},
{
"bar": true,
10: 10/20,
..
}: "world",
..
}"#,
format!("{Bar:#?}")
);
}
}
mod debug_set {
use std::fmt;
#[test]
fn test_empty() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_set().finish()
}
}
assert_eq!("{}", format!("{Foo:?}"));
assert_eq!("{}", format!("{Foo:#?}"));
}
#[test]
fn test_single() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_set().entry(&true).finish()
}
}
assert_eq!("{true}", format!("{Foo:?}"));
assert_eq!(
"{
true,
}",
format!("{Foo:#?}")
);
}
#[test]
fn test_multiple() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_set().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish()
}
}
assert_eq!("{true, 10/20}", format!("{Foo:?}"));
assert_eq!(
"{
true,
10/20,
}",
format!("{Foo:#?}")
);
}
#[test]
fn test_nested() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_set().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish()
}
}
struct Bar;
impl fmt::Debug for Bar {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_set().entry(&Foo).entry(&"world").finish()
}
}
assert_eq!(r#"{{true, 10/20}, "world"}"#, format!("{Bar:?}"));
assert_eq!(
r#"{
{
true,
10/20,
},
"world",
}"#,
format!("{Bar:#?}")
);
}
#[test]
fn test_empty_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_set().finish_non_exhaustive()
}
}
assert_eq!("{..}", format!("{Foo:?}"));
assert_eq!("{..}", format!("{Foo:#?}"));
}
#[test]
fn test_multiple_and_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_set()
.entry(&true)
.entry(&format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
assert_eq!("{true, 10/20, ..}", format!("{Foo:?}"));
assert_eq!(
"{
true,
10/20,
..
}",
format!("{Foo:#?}")
);
}
#[test]
fn test_nested_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_set()
.entry(&true)
.entry(&format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
struct Bar;
impl fmt::Debug for Bar {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_set().entry(&Foo).entry(&"world").finish_non_exhaustive()
}
}
assert_eq!(r#"{{true, 10/20, ..}, "world", ..}"#, format!("{Bar:?}"));
assert_eq!(
r#"{
{
true,
10/20,
..
},
"world",
..
}"#,
format!("{Bar:#?}")
);
}
}
mod debug_list {
use std::fmt;
#[test]
fn test_empty() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list().finish()
}
}
assert_eq!("[]", format!("{Foo:?}"));
assert_eq!("[]", format!("{Foo:#?}"));
}
#[test]
fn test_single() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list().entry(&true).finish()
}
}
assert_eq!("[true]", format!("{Foo:?}"));
assert_eq!(
"[
true,
]",
format!("{Foo:#?}")
);
}
#[test]
fn test_multiple() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish()
}
}
assert_eq!("[true, 10/20]", format!("{Foo:?}"));
assert_eq!(
"[
true,
10/20,
]",
format!("{Foo:#?}")
);
}
#[test]
fn test_nested() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish()
}
}
struct Bar;
impl fmt::Debug for Bar {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list().entry(&Foo).entry(&"world").finish()
}
}
assert_eq!(r#"[[true, 10/20], "world"]"#, format!("{Bar:?}"));
assert_eq!(
r#"[
[
true,
10/20,
],
"world",
]"#,
format!("{Bar:#?}")
);
}
#[test]
fn test_empty_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list().finish_non_exhaustive()
}
}
assert_eq!("[..]", format!("{Foo:?}"));
assert_eq!("[..]", format!("{Foo:#?}"));
}
#[test]
fn test_multiple_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list()
.entry(&true)
.entry(&format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
assert_eq!("[true, 10/20, ..]", format!("{Foo:?}"));
assert_eq!(
"[
true,
10/20,
..
]",
format!("{Foo:#?}")
);
}
#[test]
fn test_nested_non_exhaustive() {
struct Foo;
impl fmt::Debug for Foo {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list()
.entry(&true)
.entry(&format_args!("{}/{}", 10, 20))
.finish_non_exhaustive()
}
}
struct Bar;
impl fmt::Debug for Bar {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list().entry(&Foo).entry(&"world").finish_non_exhaustive()
}
}
assert_eq!(r#"[[true, 10/20, ..], "world", ..]"#, format!("{Bar:?}"));
assert_eq!(
r#"[
[
true,
10/20,
..
],
"world",
..
]"#,
format!("{Bar:#?}")
);
}
}
#[test]
fn test_formatting_parameters_are_forwarded() {
use std::collections::{BTreeMap, BTreeSet};
#[derive(Debug)]
#[allow(dead_code)]
struct Foo {
bar: u32,
baz: u32,
}
let struct_ = Foo { bar: 1024, baz: 7 };
let tuple = (1024, 7);
let list = [1024, 7];
let mut map = BTreeMap::new();
map.insert("bar", 1024);
map.insert("baz", 7);
let mut set = BTreeSet::new();
set.insert(1024);
set.insert(7);
assert_eq!(format!("{struct_:03?}"), "Foo { bar: 1024, baz: 007 }");
assert_eq!(format!("{tuple:03?}"), "(1024, 007)");
assert_eq!(format!("{list:03?}"), "[1024, 007]");
assert_eq!(format!("{map:03?}"), r#"{"bar": 1024, "baz": 007}"#);
assert_eq!(format!("{set:03?}"), "{007, 1024}");
assert_eq!(
format!("{struct_:#03?}"),
"
Foo {
bar: 1024,
baz: 007,
}
"
.trim()
);
assert_eq!(
format!("{tuple:#03?}"),
"
(
1024,
007,
)
"
.trim()
);
assert_eq!(
format!("{list:#03?}"),
"
[
1024,
007,
]
"
.trim()
);
assert_eq!(
format!("{map:#03?}"),
r#"
{
"bar": 1024,
"baz": 007,
}
"#
.trim()
);
assert_eq!(
format!("{set:#03?}"),
"
{
007,
1024,
}
"
.trim()
);
}