Skip to content

Commit 9864ec4

Browse files
committed
Implement finish_non_exhaustive for DebugStruct.
1 parent cb6122d commit 9864ec4

File tree

3 files changed

+140
-0
lines changed

3 files changed

+140
-0
lines changed

src/libcore/fmt/builders.rs

+56
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,62 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
159159
self
160160
}
161161

162+
/// Marks the struct as non-exhaustive, indicating to the reader that there are some other
163+
/// fields that are not shown in the debug representation.
164+
///
165+
/// # Examples
166+
///
167+
/// ```
168+
/// # #![feature(debug_non_exhaustive)]
169+
/// use std::fmt;
170+
///
171+
/// struct Bar {
172+
/// bar: i32,
173+
/// hidden: f32,
174+
/// }
175+
///
176+
/// impl fmt::Debug for Bar {
177+
/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
178+
/// fmt.debug_struct("Bar")
179+
/// .field("bar", &self.bar)
180+
/// .finish_non_exhaustive() // Show that some other field(s) exist.
181+
/// }
182+
/// }
183+
///
184+
/// assert_eq!(
185+
/// format!("{:?}", Bar { bar: 10, hidden: 1.0 }),
186+
/// "Bar { bar: 10, .. }",
187+
/// );
188+
/// ```
189+
#[unstable(feature = "debug_non_exhaustive", issue = "67364")]
190+
pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
191+
self.result = self.result.and_then(|_| {
192+
// Draw non-exhaustive dots (`..`), and open brace if necessary (no fields).
193+
if self.is_pretty() {
194+
if !self.has_fields {
195+
self.fmt.write_str(" {\n")?;
196+
}
197+
let mut slot = None;
198+
let mut state = Default::default();
199+
let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state);
200+
writer.write_str("..\n")?;
201+
} else {
202+
if self.has_fields {
203+
self.fmt.write_str(", ..")?;
204+
} else {
205+
self.fmt.write_str(" { ..")?;
206+
}
207+
}
208+
if self.is_pretty() {
209+
self.fmt.write_str("}")?
210+
} else {
211+
self.fmt.write_str(" }")?;
212+
}
213+
Ok(())
214+
});
215+
self.result
216+
}
217+
162218
/// Finishes output and returns any error encountered.
163219
///
164220
/// # Examples

src/libcore/tests/fmt/builders.rs

+83
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,89 @@ mod debug_struct {
9393
format!("{:#?}", Bar)
9494
);
9595
}
96+
97+
#[test]
98+
fn test_only_non_exhaustive() {
99+
struct Foo;
100+
101+
impl fmt::Debug for Foo {
102+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
103+
fmt.debug_struct("Foo")
104+
.finish_non_exhaustive()
105+
}
106+
}
107+
108+
109+
assert_eq!("Foo { .. }", format!("{:?}", Foo));
110+
assert_eq!(
111+
"Foo {
112+
..
113+
}",
114+
format!("{:#?}", Foo));
115+
}
116+
117+
#[test]
118+
fn test_multiple_and_non_exhaustive() {
119+
struct Foo;
120+
121+
impl fmt::Debug for Foo {
122+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
123+
fmt.debug_struct("Foo")
124+
.field("bar", &true)
125+
.field("baz", &format_args!("{}/{}", 10, 20))
126+
.finish_non_exhaustive()
127+
}
128+
}
129+
130+
assert_eq!("Foo { bar: true, baz: 10/20, .. }", format!("{:?}", Foo));
131+
assert_eq!(
132+
"Foo {
133+
bar: true,
134+
baz: 10/20,
135+
..
136+
}",
137+
format!("{:#?}", Foo));
138+
}
139+
140+
#[test]
141+
fn test_nested_non_exhaustive() {
142+
struct Foo;
143+
144+
impl fmt::Debug for Foo {
145+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
146+
fmt.debug_struct("Foo")
147+
.field("bar", &true)
148+
.field("baz", &format_args!("{}/{}", 10, 20))
149+
.finish_non_exhaustive()
150+
}
151+
}
152+
153+
struct Bar;
154+
155+
impl fmt::Debug for Bar {
156+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
157+
fmt.debug_struct("Bar")
158+
.field("foo", &Foo)
159+
.field("hello", &"world")
160+
.finish_non_exhaustive()
161+
}
162+
}
163+
164+
assert_eq!("Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }",
165+
format!("{:?}", Bar));
166+
assert_eq!(
167+
"Bar {
168+
foo: Foo {
169+
bar: true,
170+
baz: 10/20,
171+
..
172+
},
173+
hello: \"world\",
174+
..
175+
}",
176+
format!("{:#?}", Bar));
177+
}
178+
96179
}
97180

98181
mod debug_tuple {

src/libcore/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![feature(core_private_bignum)]
66
#![feature(core_private_diy_float)]
77
#![feature(debug_map_key_value)]
8+
#![feature(debug_non_exhaustive)]
89
#![feature(dec2flt)]
910
#![feature(exact_size_is_empty)]
1011
#![feature(fixed_size_array)]

0 commit comments

Comments
 (0)