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.
Links and related work
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):
- We think this problem seems worth solving, and the standard library might be the right place to solve it.
- We think that this probably doesn't belong in the standard library.
Second, if there's a concrete solution:
- We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
- We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.