ACP: Add finish_non_exhaustive to DebugList, DebugMap, andDebugTuple · Issue #248 · rust-lang/libs-team (original) (raw)

Proposal

Problem statement

Many formatting implementations may want to print only a subset of items from a list, set, or map. Subsets can be printed directly (e.g., .item(my_slice[..10])) but there is no clear way to indicate that there are more elements not dislayed.

Motivating examples or use cases

Currently, one of the best solutions to showing non exhaustiveness looks as follows, in this simple wrapper type that prints up to 6 elements in a buffer:

struct TruncatedPrinter<'a, T>(&'a [T]);

impl<'a, T: fmt::Debug> fmt::Display for TruncatedPrinter<'a, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // print at most 6 elements (don't ever omit the .., for simplicity) let to_print = min(self.0.len(), 6); f.debug_list().entries(self.0[..to_print]).entry(&{..}).finish() } }

The output looks like the following:

This is correct, but (1) is less clear and less discoverable than finish_non_exhaustive, and (2) relies on the debug implementation of RangeFull (though this is unlikely to change).

Solution sketch

This proposes adding a finish_non_exhaustive method to other DebugX types, to mirror what is already possible with DebugStruct. New API would be:

impl<'a, 'b: 'a> DebugList<'a, 'b> { pub fn finish_non_exhaustive(&mut self) -> Result<(), Error>; }

impl<'a, 'b: 'a> DebugMap<'a, 'b> { pub fn finish_non_exhaustive(&mut self) -> Result<(), Error>; }

impl<'a, 'b: 'a> DebugTuple<'a, 'b> { pub fn finish_non_exhaustive(&mut self) -> Result<(), Error>; }

Each of these results should add an element .. to the output list, similar to DebugStruct's behavior.

Alternatives

An alternative could be to provide a NonExhaustive element that implements Debug and prints .., which could be passed to entry. This would have the advantage of giving an easy way to omit items in the middle of a list, e.g. [1, 2, ..., 6], and would be more clear than the status quo &{..}.

This option was not included in order to match DebugStruct's precedent.

Existing API: DebugStruct::finish_non_exhaustive

debug_non_exhaustive discussion and implmentation: rust-lang/rust#67364

That issue does discuss adding the implementation for other DebugX types, but I do not see any specific reason that they were excluded outside of keeping the MVP minimal. There are a few comments expressing desire for DebugTuple to provide this method.

What happens now?

This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.

Possible responses

The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):

Second, if there's a concrete solution: