Skip to content

Commit 9c299bc

Browse files
committed
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 <rust-lang/libs-team#248>.
1 parent b405024 commit 9c299bc

File tree

3 files changed

+521
-2
lines changed

3 files changed

+521
-2
lines changed

Diff for: core/src/fmt/builders.rs

+200
Original file line numberDiff line numberDiff line change
@@ -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
@@ -554,6 +599,56 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
554599
self
555600
}
556601

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

795+
/// Marks the list as non-exhaustive, indicating to the reader that there are some other
796+
/// elements that are not shown in the debug representation.
797+
///
798+
/// # Examples
799+
///
800+
/// ```
801+
/// #![feature(debug_more_non_exhaustive)]
802+
///
803+
/// use std::fmt;
804+
///
805+
/// struct Foo(Vec<i32>);
806+
///
807+
/// impl fmt::Debug for Foo {
808+
/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
809+
/// // Print at most two elements, abbreviate the rest
810+
/// let mut f = fmt.debug_list();
811+
/// let mut f = f.entries(self.0.iter().take(2));
812+
/// if self.0.len() > 2 {
813+
/// f.finish_non_exhaustive()
814+
/// } else {
815+
/// f.finish()
816+
/// }
817+
/// }
818+
/// }
819+
///
820+
/// assert_eq!(
821+
/// format!("{:?}", Foo(vec![1, 2, 3, 4])),
822+
/// "[1, 2, ..]",
823+
/// );
824+
/// ```
825+
#[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
826+
pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
827+
self.inner.result.and_then(|_| {
828+
if self.inner.has_fields {
829+
if self.inner.is_pretty() {
830+
let mut slot = None;
831+
let mut state = Default::default();
832+
let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
833+
writer.write_str("..\n")?;
834+
self.inner.fmt.write_str("]")
835+
} else {
836+
self.inner.fmt.write_str(", ..]")
837+
}
838+
} else {
839+
self.inner.fmt.write_str("..]")
840+
}
841+
})
842+
}
843+
700844
/// Finishes output and returns any error encountered.
701845
///
702846
/// # Examples
@@ -973,6 +1117,62 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
9731117
self
9741118
}
9751119

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

0 commit comments

Comments
 (0)