Skip to content

Commit

Permalink
Rollup merge of #127945 - tgross35:debug-more-non-exhaustive, r=Norat…
Browse files Browse the repository at this point in the history
…rieb

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: #127942
  • Loading branch information
matthiaskrgr committed Aug 21, 2024
2 parents 221b53c + 827970e commit 65386c0
Show file tree
Hide file tree
Showing 3 changed files with 565 additions and 46 deletions.
224 changes: 212 additions & 12 deletions library/core/src/fmt/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl fmt::Write for PadAdapter<'_, '_> {
///
/// assert_eq!(
/// format!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }),
/// "Foo { bar: 10, baz: \"Hello World\" }",
/// r#"Foo { bar: 10, baz: "Hello World" }"#,
/// );
/// ```
#[must_use = "must eventually call `finish()` on Debug builders"]
Expand Down Expand Up @@ -125,7 +125,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Bar { bar: 10, another: "Hello World".to_string() }),
/// "Bar { bar: 10, another: \"Hello World\", nonexistent_field: 1 }",
/// r#"Bar { bar: 10, another: "Hello World", nonexistent_field: 1 }"#,
/// );
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
Expand Down Expand Up @@ -237,7 +237,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Bar { bar: 10, baz: "Hello World".to_string() }),
/// "Bar { bar: 10, baz: \"Hello World\" }",
/// r#"Bar { bar: 10, baz: "Hello World" }"#,
/// );
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
Expand Down Expand Up @@ -280,7 +280,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Foo(10, "Hello World".to_string())),
/// "Foo(10, \"Hello World\")",
/// r#"Foo(10, "Hello World")"#,
/// );
/// ```
#[must_use = "must eventually call `finish()` on Debug builders"]
Expand Down Expand Up @@ -322,7 +322,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Foo(10, "Hello World".to_string())),
/// "Foo(10, \"Hello World\")",
/// r#"Foo(10, "Hello World")"#,
/// );
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
Expand Down Expand Up @@ -360,6 +360,51 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
self
}

/// Marks the tuple struct as non-exhaustive, indicating to the reader that there are some
/// other fields that are not shown in the debug representation.
///
/// # Examples
///
/// ```
/// #![feature(debug_more_non_exhaustive)]
///
/// use std::fmt;
///
/// struct Foo(i32, String);
///
/// impl fmt::Debug for Foo {
/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
/// fmt.debug_tuple("Foo")
/// .field(&self.0)
/// .finish_non_exhaustive() // Show that some other field(s) exist.
/// }
/// }
///
/// assert_eq!(
/// format!("{:?}", Foo(10, "secret!".to_owned())),
/// "Foo(10, ..)",
/// );
/// ```
#[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
self.result = self.result.and_then(|_| {
if self.fields > 0 {
if self.is_pretty() {
let mut slot = None;
let mut state = Default::default();
let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
writer.write_str("..\n")?;
self.fmt.write_str(")")
} else {
self.fmt.write_str(", ..)")
}
} else {
self.fmt.write_str("(..)")
}
});
self.result
}

/// Finishes output and returns any error encountered.
///
/// # Examples
Expand All @@ -381,7 +426,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Foo(10, "Hello World".to_string())),
/// "Foo(10, \"Hello World\")",
/// r#"Foo(10, "Hello World")"#,
/// );
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
Expand Down Expand Up @@ -555,6 +600,56 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
self
}

/// Marks the set as non-exhaustive, indicating to the reader that there are some other
/// elements that are not shown in the debug representation.
///
/// # Examples
///
/// ```
/// #![feature(debug_more_non_exhaustive)]
///
/// use std::fmt;
///
/// struct Foo(Vec<i32>);
///
/// impl fmt::Debug for Foo {
/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
/// // Print at most two elements, abbreviate the rest
/// let mut f = fmt.debug_set();
/// let mut f = f.entries(self.0.iter().take(2));
/// if self.0.len() > 2 {
/// f.finish_non_exhaustive()
/// } else {
/// f.finish()
/// }
/// }
/// }
///
/// assert_eq!(
/// format!("{:?}", Foo(vec![1, 2, 3, 4])),
/// "{1, 2, ..}",
/// );
/// ```
#[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
self.inner.result = self.inner.result.and_then(|_| {
if self.inner.has_fields {
if self.inner.is_pretty() {
let mut slot = None;
let mut state = Default::default();
let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
writer.write_str("..\n")?;
self.inner.fmt.write_str("}")
} else {
self.inner.fmt.write_str(", ..}")
}
} else {
self.inner.fmt.write_str("..}")
}
});
self.inner.result
}

/// Finishes output and returns any error encountered.
///
/// # Examples
Expand Down Expand Up @@ -699,6 +794,55 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
self
}

/// Marks the list as non-exhaustive, indicating to the reader that there are some other
/// elements that are not shown in the debug representation.
///
/// # Examples
///
/// ```
/// #![feature(debug_more_non_exhaustive)]
///
/// use std::fmt;
///
/// struct Foo(Vec<i32>);
///
/// impl fmt::Debug for Foo {
/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
/// // Print at most two elements, abbreviate the rest
/// let mut f = fmt.debug_list();
/// let mut f = f.entries(self.0.iter().take(2));
/// if self.0.len() > 2 {
/// f.finish_non_exhaustive()
/// } else {
/// f.finish()
/// }
/// }
/// }
///
/// assert_eq!(
/// format!("{:?}", Foo(vec![1, 2, 3, 4])),
/// "[1, 2, ..]",
/// );
/// ```
#[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
self.inner.result.and_then(|_| {
if self.inner.has_fields {
if self.inner.is_pretty() {
let mut slot = None;
let mut state = Default::default();
let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
writer.write_str("..\n")?;
self.inner.fmt.write_str("]")
} else {
self.inner.fmt.write_str(", ..]")
}
} else {
self.inner.fmt.write_str("..]")
}
})
}

/// Finishes output and returns any error encountered.
///
/// # Examples
Expand Down Expand Up @@ -750,7 +894,7 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
/// "{\"A\": 10, \"B\": 11}",
/// r#"{"A": 10, "B": 11}"#,
/// );
/// ```
#[must_use = "must eventually call `finish()` on Debug builders"]
Expand Down Expand Up @@ -790,7 +934,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
/// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
/// r#"{"whole": [("A", 10), ("B", 11)]}"#,
/// );
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
Expand Down Expand Up @@ -826,7 +970,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
/// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
/// r#"{"whole": [("A", 10), ("B", 11)]}"#,
/// );
/// ```
#[stable(feature = "debug_map_key_value", since = "1.42.0")]
Expand Down Expand Up @@ -902,7 +1046,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
/// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
/// r#"{"whole": [("A", 10), ("B", 11)]}"#,
/// );
/// ```
#[stable(feature = "debug_map_key_value", since = "1.42.0")]
Expand Down Expand Up @@ -960,7 +1104,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
/// "{\"A\": 10, \"B\": 11}",
/// r#"{"A": 10, "B": 11}"#,
/// );
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
Expand All @@ -976,6 +1120,62 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
self
}

/// Marks the map as non-exhaustive, indicating to the reader that there are some other
/// entries that are not shown in the debug representation.
///
/// # Examples
///
/// ```
/// #![feature(debug_more_non_exhaustive)]
///
/// use std::fmt;
///
/// struct Foo(Vec<(String, i32)>);
///
/// impl fmt::Debug for Foo {
/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
/// // Print at most two elements, abbreviate the rest
/// let mut f = fmt.debug_map();
/// let mut f = f.entries(self.0.iter().take(2).map(|&(ref k, ref v)| (k, v)));
/// if self.0.len() > 2 {
/// f.finish_non_exhaustive()
/// } else {
/// f.finish()
/// }
/// }
/// }
///
/// assert_eq!(
/// format!("{:?}", Foo(vec![
/// ("A".to_string(), 10),
/// ("B".to_string(), 11),
/// ("C".to_string(), 12),
/// ])),
/// r#"{"A": 10, "B": 11, ..}"#,
/// );
/// ```
#[unstable(feature = "debug_more_non_exhaustive", issue = "127942")]
pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
self.result = self.result.and_then(|_| {
assert!(!self.has_key, "attempted to finish a map with a partial entry");

if self.has_fields {
if self.is_pretty() {
let mut slot = None;
let mut state = Default::default();
let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
writer.write_str("..\n")?;
self.fmt.write_str("}")
} else {
self.fmt.write_str(", ..}")
}
} else {
self.fmt.write_str("..}")
}
});
self.result
}

/// Finishes output and returns any error encountered.
///
/// # Panics
Expand All @@ -1000,7 +1200,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
///
/// assert_eq!(
/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
/// "{\"A\": 10, \"B\": 11}",
/// r#"{"A": 10, "B": 11}"#,
/// );
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
Expand Down
Loading

0 comments on commit 65386c0

Please sign in to comment.