Skip to content

Commit

Permalink
Implement debug_more_non_exhaustive
Browse files Browse the repository at this point in the history
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>.
  • Loading branch information
tgross35 committed Jul 21, 2024
1 parent 6d32b66 commit 3ad47c7
Show file tree
Hide file tree
Showing 3 changed files with 520 additions and 0 deletions.
200 changes: 200 additions & 0 deletions library/core/src/fmt/builders.rs
Original file line number Diff line number Diff line change
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 Down Expand Up @@ -554,6 +599,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 @@ -697,6 +792,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 @@ -973,6 +1117,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 Down
Loading

0 comments on commit 3ad47c7

Please sign in to comment.