Skip to content

Commit dbd21e7

Browse files
authored
Unrolled build for rust-lang#127945
Rollup merge of rust-lang#127945 - tgross35:debug-more-non-exhaustive, r=Noratrieb Implement `debug_more_non_exhaustive` This implements the ACP at rust-lang/libs-team#248, adding `.finish_non_exhaustive()` for `DebugTuple`, `DebugSet`, `DebugList`, and `DebugMap`. Also used this as an opportunity to make some documentation and tests more readable by using raw strings instead of escaped quotes. Tracking issue: rust-lang#127942
2 parents a32d4a0 + 827970e commit dbd21e7

File tree

3 files changed

+565
-46
lines changed

3 files changed

+565
-46
lines changed

library/core/src/fmt/builders.rs

+212-12
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl fmt::Write for PadAdapter<'_, '_> {
7878
///
7979
/// assert_eq!(
8080
/// format!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }),
81-
/// "Foo { bar: 10, baz: \"Hello World\" }",
81+
/// r#"Foo { bar: 10, baz: "Hello World" }"#,
8282
/// );
8383
/// ```
8484
#[must_use = "must eventually call `finish()` on Debug builders"]
@@ -125,7 +125,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
125125
///
126126
/// assert_eq!(
127127
/// format!("{:?}", Bar { bar: 10, another: "Hello World".to_string() }),
128-
/// "Bar { bar: 10, another: \"Hello World\", nonexistent_field: 1 }",
128+
/// r#"Bar { bar: 10, another: "Hello World", nonexistent_field: 1 }"#,
129129
/// );
130130
/// ```
131131
#[stable(feature = "debug_builders", since = "1.2.0")]
@@ -237,7 +237,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
237237
///
238238
/// assert_eq!(
239239
/// format!("{:?}", Bar { bar: 10, baz: "Hello World".to_string() }),
240-
/// "Bar { bar: 10, baz: \"Hello World\" }",
240+
/// r#"Bar { bar: 10, baz: "Hello World" }"#,
241241
/// );
242242
/// ```
243243
#[stable(feature = "debug_builders", since = "1.2.0")]
@@ -280,7 +280,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
280280
///
281281
/// assert_eq!(
282282
/// format!("{:?}", Foo(10, "Hello World".to_string())),
283-
/// "Foo(10, \"Hello World\")",
283+
/// r#"Foo(10, "Hello World")"#,
284284
/// );
285285
/// ```
286286
#[must_use = "must eventually call `finish()` on Debug builders"]
@@ -322,7 +322,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
322322
///
323323
/// assert_eq!(
324324
/// format!("{:?}", Foo(10, "Hello World".to_string())),
325-
/// "Foo(10, \"Hello World\")",
325+
/// r#"Foo(10, "Hello World")"#,
326326
/// );
327327
/// ```
328328
#[stable(feature = "debug_builders", since = "1.2.0")]
@@ -360,6 +360,51 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
360360
self
361361
}
362362

363+
/// Marks the tuple struct as non-exhaustive, indicating to the reader that there are some
364+
/// other fields that are not shown in the debug representation.
365+
///
366+
/// # Examples
367+
///
368+
/// ```
369+
/// #![feature(debug_more_non_exhaustive)]
370+
///
371+
/// use std::fmt;
372+
///
373+
/// struct Foo(i32, String);
374+
///
375+
/// impl fmt::Debug for Foo {
376+
/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
377+
/// fmt.debug_tuple("Foo")
378+
/// .field(&self.0)
379+
/// .finish_non_exhaustive() // Show that some other field(s) exist.
380+
/// }
381+
/// }
382+
///
383+
/// assert_eq!(
384+
/// format!("{:?}", Foo(10, "secret!".to_owned())),
385+
/// "Foo(10, ..)",
386+
/// );
387+
/// ```
388+
#[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
389+
pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
390+
self.result = self.result.and_then(|_| {
391+
if self.fields > 0 {
392+
if self.is_pretty() {
393+
let mut slot = None;
394+
let mut state = Default::default();
395+
let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
396+
writer.write_str("..\n")?;
397+
self.fmt.write_str(")")
398+
} else {
399+
self.fmt.write_str(", ..)")
400+
}
401+
} else {
402+
self.fmt.write_str("(..)")
403+
}
404+
});
405+
self.result
406+
}
407+
363408
/// Finishes output and returns any error encountered.
364409
///
365410
/// # Examples
@@ -381,7 +426,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
381426
///
382427
/// assert_eq!(
383428
/// format!("{:?}", Foo(10, "Hello World".to_string())),
384-
/// "Foo(10, \"Hello World\")",
429+
/// r#"Foo(10, "Hello World")"#,
385430
/// );
386431
/// ```
387432
#[stable(feature = "debug_builders", since = "1.2.0")]
@@ -555,6 +600,56 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
555600
self
556601
}
557602

603+
/// Marks the set as non-exhaustive, indicating to the reader that there are some other
604+
/// elements that are not shown in the debug representation.
605+
///
606+
/// # Examples
607+
///
608+
/// ```
609+
/// #![feature(debug_more_non_exhaustive)]
610+
///
611+
/// use std::fmt;
612+
///
613+
/// struct Foo(Vec<i32>);
614+
///
615+
/// impl fmt::Debug for Foo {
616+
/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
617+
/// // Print at most two elements, abbreviate the rest
618+
/// let mut f = fmt.debug_set();
619+
/// let mut f = f.entries(self.0.iter().take(2));
620+
/// if self.0.len() > 2 {
621+
/// f.finish_non_exhaustive()
622+
/// } else {
623+
/// f.finish()
624+
/// }
625+
/// }
626+
/// }
627+
///
628+
/// assert_eq!(
629+
/// format!("{:?}", Foo(vec![1, 2, 3, 4])),
630+
/// "{1, 2, ..}",
631+
/// );
632+
/// ```
633+
#[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
634+
pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
635+
self.inner.result = self.inner.result.and_then(|_| {
636+
if self.inner.has_fields {
637+
if self.inner.is_pretty() {
638+
let mut slot = None;
639+
let mut state = Default::default();
640+
let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
641+
writer.write_str("..\n")?;
642+
self.inner.fmt.write_str("}")
643+
} else {
644+
self.inner.fmt.write_str(", ..}")
645+
}
646+
} else {
647+
self.inner.fmt.write_str("..}")
648+
}
649+
});
650+
self.inner.result
651+
}
652+
558653
/// Finishes output and returns any error encountered.
559654
///
560655
/// # Examples
@@ -699,6 +794,55 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
699794
self
700795
}
701796

797+
/// Marks the list as non-exhaustive, indicating to the reader that there are some other
798+
/// elements that are not shown in the debug representation.
799+
///
800+
/// # Examples
801+
///
802+
/// ```
803+
/// #![feature(debug_more_non_exhaustive)]
804+
///
805+
/// use std::fmt;
806+
///
807+
/// struct Foo(Vec<i32>);
808+
///
809+
/// impl fmt::Debug for Foo {
810+
/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
811+
/// // Print at most two elements, abbreviate the rest
812+
/// let mut f = fmt.debug_list();
813+
/// let mut f = f.entries(self.0.iter().take(2));
814+
/// if self.0.len() > 2 {
815+
/// f.finish_non_exhaustive()
816+
/// } else {
817+
/// f.finish()
818+
/// }
819+
/// }
820+
/// }
821+
///
822+
/// assert_eq!(
823+
/// format!("{:?}", Foo(vec![1, 2, 3, 4])),
824+
/// "[1, 2, ..]",
825+
/// );
826+
/// ```
827+
#[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
828+
pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
829+
self.inner.result.and_then(|_| {
830+
if self.inner.has_fields {
831+
if self.inner.is_pretty() {
832+
let mut slot = None;
833+
let mut state = Default::default();
834+
let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
835+
writer.write_str("..\n")?;
836+
self.inner.fmt.write_str("]")
837+
} else {
838+
self.inner.fmt.write_str(", ..]")
839+
}
840+
} else {
841+
self.inner.fmt.write_str("..]")
842+
}
843+
})
844+
}
845+
702846
/// Finishes output and returns any error encountered.
703847
///
704848
/// # Examples
@@ -750,7 +894,7 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
750894
///
751895
/// assert_eq!(
752896
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
753-
/// "{\"A\": 10, \"B\": 11}",
897+
/// r#"{"A": 10, "B": 11}"#,
754898
/// );
755899
/// ```
756900
#[must_use = "must eventually call `finish()` on Debug builders"]
@@ -790,7 +934,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
790934
///
791935
/// assert_eq!(
792936
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
793-
/// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
937+
/// r#"{"whole": [("A", 10), ("B", 11)]}"#,
794938
/// );
795939
/// ```
796940
#[stable(feature = "debug_builders", since = "1.2.0")]
@@ -826,7 +970,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
826970
///
827971
/// assert_eq!(
828972
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
829-
/// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
973+
/// r#"{"whole": [("A", 10), ("B", 11)]}"#,
830974
/// );
831975
/// ```
832976
#[stable(feature = "debug_map_key_value", since = "1.42.0")]
@@ -902,7 +1046,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
9021046
///
9031047
/// assert_eq!(
9041048
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
905-
/// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
1049+
/// r#"{"whole": [("A", 10), ("B", 11)]}"#,
9061050
/// );
9071051
/// ```
9081052
#[stable(feature = "debug_map_key_value", since = "1.42.0")]
@@ -960,7 +1104,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
9601104
///
9611105
/// assert_eq!(
9621106
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
963-
/// "{\"A\": 10, \"B\": 11}",
1107+
/// r#"{"A": 10, "B": 11}"#,
9641108
/// );
9651109
/// ```
9661110
#[stable(feature = "debug_builders", since = "1.2.0")]
@@ -976,6 +1120,62 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
9761120
self
9771121
}
9781122

1123+
/// Marks the map as non-exhaustive, indicating to the reader that there are some other
1124+
/// entries that are not shown in the debug representation.
1125+
///
1126+
/// # Examples
1127+
///
1128+
/// ```
1129+
/// #![feature(debug_more_non_exhaustive)]
1130+
///
1131+
/// use std::fmt;
1132+
///
1133+
/// struct Foo(Vec<(String, i32)>);
1134+
///
1135+
/// impl fmt::Debug for Foo {
1136+
/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1137+
/// // Print at most two elements, abbreviate the rest
1138+
/// let mut f = fmt.debug_map();
1139+
/// let mut f = f.entries(self.0.iter().take(2).map(|&(ref k, ref v)| (k, v)));
1140+
/// if self.0.len() > 2 {
1141+
/// f.finish_non_exhaustive()
1142+
/// } else {
1143+
/// f.finish()
1144+
/// }
1145+
/// }
1146+
/// }
1147+
///
1148+
/// assert_eq!(
1149+
/// format!("{:?}", Foo(vec![
1150+
/// ("A".to_string(), 10),
1151+
/// ("B".to_string(), 11),
1152+
/// ("C".to_string(), 12),
1153+
/// ])),
1154+
/// r#"{"A": 10, "B": 11, ..}"#,
1155+
/// );
1156+
/// ```
1157+
#[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
1158+
pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
1159+
self.result = self.result.and_then(|_| {
1160+
assert!(!self.has_key, "attempted to finish a map with a partial entry");
1161+
1162+
if self.has_fields {
1163+
if self.is_pretty() {
1164+
let mut slot = None;
1165+
let mut state = Default::default();
1166+
let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
1167+
writer.write_str("..\n")?;
1168+
self.fmt.write_str("}")
1169+
} else {
1170+
self.fmt.write_str(", ..}")
1171+
}
1172+
} else {
1173+
self.fmt.write_str("..}")
1174+
}
1175+
});
1176+
self.result
1177+
}
1178+
9791179
/// Finishes output and returns any error encountered.
9801180
///
9811181
/// # Panics
@@ -1000,7 +1200,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
10001200
///
10011201
/// assert_eq!(
10021202
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1003-
/// "{\"A\": 10, \"B\": 11}",
1203+
/// r#"{"A": 10, "B": 11}"#,
10041204
/// );
10051205
/// ```
10061206
#[stable(feature = "debug_builders", since = "1.2.0")]

0 commit comments

Comments
 (0)