Rollup merge of #117730 - jmillikin:fmt-debug-helper-fns, r=cuviper · rust-lang/rust@0f1da7e
@@ -130,6 +130,18 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
130130 /// ```
131131 #[stable(feature = "debug_builders", since = "1.2.0")]
132132pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut Self {
133+self.field_with(name, |f| value.fmt(f))
134+}
135+136+/// Adds a new field to the generated struct output.
137+ ///
138+ /// This method is equivalent to [`DebugStruct::field`], but formats the
139+ /// value using a provided closure rather than by calling [`Debug::fmt`].
140+ #[unstable(feature = "debug_closure_helpers", issue = "117729")]
141+pub fn field_with<F>(&mut self, name: &str, value_fmt: F) -> &mut Self
142+where
143+F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
144+{
133145self.result = self.result.and_then(|_| {
134146if self.is_pretty() {
135147if !self.has_fields {
@@ -140,14 +152,14 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
140152let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
141153 writer.write_str(name)?;
142154 writer.write_str(": ")?;
143-value.fmt(&mut writer)?;
155+value_fmt(&mut writer)?;
144156 writer.write_str(",\n")
145157} else {
146158let prefix = if self.has_fields { ", " } else { " { " };
147159self.fmt.write_str(prefix)?;
148160self.fmt.write_str(name)?;
149161self.fmt.write_str(": ")?;
150-value.fmt(self.fmt)
162+value_fmt(self.fmt)
151163}
152164});
153165@@ -315,6 +327,18 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
315327 /// ```
316328 #[stable(feature = "debug_builders", since = "1.2.0")]
317329pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut Self {
330+self.field_with(|f| value.fmt(f))
331+}
332+333+/// Adds a new field to the generated tuple struct output.
334+ ///
335+ /// This method is equivalent to [`DebugTuple::field`], but formats the
336+ /// value using a provided closure rather than by calling [`Debug::fmt`].
337+ #[unstable(feature = "debug_closure_helpers", issue = "117729")]
338+pub fn field_with<F>(&mut self, value_fmt: F) -> &mut Self
339+where
340+F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
341+{
318342self.result = self.result.and_then(|_| {
319343if self.is_pretty() {
320344if self.fields == 0 {
@@ -323,12 +347,12 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
323347let mut slot = None;
324348let mut state = Default::default();
325349let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
326-value.fmt(&mut writer)?;
350+value_fmt(&mut writer)?;
327351 writer.write_str(",\n")
328352} else {
329353let prefix = if self.fields == 0 { "(" } else { ", " };
330354self.fmt.write_str(prefix)?;
331-value.fmt(self.fmt)
355+value_fmt(self.fmt)
332356}
333357});
334358@@ -385,7 +409,10 @@ struct DebugInner<'a, 'b: 'a> {
385409}
386410387411impl<'a, 'b: 'a> DebugInner<'a, 'b> {
388-fn entry(&mut self, entry: &dyn fmt::Debug) {
412+fn entry_with<F>(&mut self, entry_fmt: F)
413+where
414+F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
415+{
389416self.result = self.result.and_then(|_| {
390417if self.is_pretty() {
391418if !self.has_fields {
@@ -394,13 +421,13 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {
394421let mut slot = None;
395422let mut state = Default::default();
396423let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
397-entry.fmt(&mut writer)?;
424+entry_fmt(&mut writer)?;
398425 writer.write_str(",\n")
399426} else {
400427if self.has_fields {
401428self.fmt.write_str(", ")?
402429}
403-entry.fmt(self.fmt)
430+entry_fmt(self.fmt)
404431}
405432});
406433@@ -475,7 +502,20 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
475502 /// ```
476503 #[stable(feature = "debug_builders", since = "1.2.0")]
477504pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
478-self.inner.entry(entry);
505+self.inner.entry_with(|f| entry.fmt(f));
506+self
507+}
508+509+/// Adds a new entry to the set output.
510+ ///
511+ /// This method is equivalent to [`DebugSet::entry`], but formats the
512+ /// entry using a provided closure rather than by calling [`Debug::fmt`].
513+ #[unstable(feature = "debug_closure_helpers", issue = "117729")]
514+pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self
515+where
516+F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
517+{
518+self.inner.entry_with(entry_fmt);
479519self
480520}
481521@@ -605,7 +645,20 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
605645 /// ```
606646 #[stable(feature = "debug_builders", since = "1.2.0")]
607647pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
608-self.inner.entry(entry);
648+self.inner.entry_with(|f| entry.fmt(f));
649+self
650+}
651+652+/// Adds a new entry to the list output.
653+ ///
654+ /// This method is equivalent to [`DebugList::entry`], but formats the
655+ /// entry using a provided closure rather than by calling [`Debug::fmt`].
656+ #[unstable(feature = "debug_closure_helpers", issue = "117729")]
657+pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self
658+where
659+F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
660+{
661+self.inner.entry_with(entry_fmt);
609662self
610663}
611664@@ -775,6 +828,18 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
775828 /// ```
776829 #[stable(feature = "debug_map_key_value", since = "1.42.0")]
777830pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut Self {
831+self.key_with(|f| key.fmt(f))
832+}
833+834+/// Adds the key part of a new entry to the map output.
835+ ///
836+ /// This method is equivalent to [`DebugMap::key`], but formats the
837+ /// key using a provided closure rather than by calling [`Debug::fmt`].
838+ #[unstable(feature = "debug_closure_helpers", issue = "117729")]
839+pub fn key_with<F>(&mut self, key_fmt: F) -> &mut Self
840+where
841+F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
842+{
778843self.result = self.result.and_then(|_| {
779844assert!(
780845 !self.has_key,
@@ -789,13 +854,13 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
789854let mut slot = None;
790855self.state = Default::default();
791856let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);
792-key.fmt(&mut writer)?;
857+key_fmt(&mut writer)?;
793858 writer.write_str(": ")?;
794859} else {
795860if self.has_fields {
796861self.fmt.write_str(", ")?
797862}
798-key.fmt(self.fmt)?;
863+key_fmt(self.fmt)?;
799864self.fmt.write_str(": ")?;
800865}
801866@@ -839,16 +904,28 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
839904 /// ```
840905 #[stable(feature = "debug_map_key_value", since = "1.42.0")]
841906pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut Self {
907+self.value_with(|f| value.fmt(f))
908+}
909+910+/// Adds the value part of a new entry to the map output.
911+ ///
912+ /// This method is equivalent to [`DebugMap::value`], but formats the
913+ /// value using a provided closure rather than by calling [`Debug::fmt`].
914+ #[unstable(feature = "debug_closure_helpers", issue = "117729")]
915+pub fn value_with<F>(&mut self, value_fmt: F) -> &mut Self
916+where
917+F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
918+{
842919self.result = self.result.and_then(|_| {
843920assert!(self.has_key, "attempted to format a map value before its key");
844921845922if self.is_pretty() {
846923let mut slot = None;
847924let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);
848-value.fmt(&mut writer)?;
925+value_fmt(&mut writer)?;
849926 writer.write_str(",\n")?;
850927} else {
851-value.fmt(self.fmt)?;
928+value_fmt(self.fmt)?;
852929}
853930854931self.has_key = false;
@@ -936,3 +1013,44 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
9361013self.fmt.alternate()
9371014}
9381015}
1016+1017+/// Implements [`fmt::Debug`] and [`fmt::Display`] using a function.
1018+///
1019+/// # Examples
1020+///
1021+/// ```
1022+/// #![feature(debug_closure_helpers)]
1023+/// use std::fmt;
1024+///
1025+/// let value = 'a';
1026+/// assert_eq!(format!("{}", value), "a");
1027+/// assert_eq!(format!("{:?}", value), "'a'");
1028+///
1029+/// let wrapped = fmt::FormatterFn(|f| write!(f, "{:?}", &value));
1030+/// assert_eq!(format!("{}", wrapped), "'a'");
1031+/// assert_eq!(format!("{:?}", wrapped), "'a'");
1032+/// ```
1033+#[unstable(feature = "debug_closure_helpers", issue = "117729")]
1034+pub struct FormatterFn<F>(pub F)
1035+where
1036+F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result;
1037+1038+#[unstable(feature = "debug_closure_helpers", issue = "117729")]
1039+impl<F> fmt::Debug for FormatterFn<F>
1040+where
1041+F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
1042+{
1043+fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1044+(self.0)(f)
1045+}
1046+}
1047+1048+#[unstable(feature = "debug_closure_helpers", issue = "117729")]
1049+impl<F> fmt::Display for FormatterFn<F>
1050+where
1051+F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
1052+{
1053+fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1054+(self.0)(f)
1055+}
1056+}