-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closure-consuming helper functions for Debug{Struct,List,Set,Tuple}
#288
Comments
Seems like really all you need is a way to write into impl fmt::Debug for FancyBitset {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("FancyBitset ")?;
let mut dbg = f.debug_set();
for bit in 0..32 {
let mask: u32 = 1 << bit;
if self.0 & mask == 0 {
continue;
}
match FancyBitset(mask) {
FancyBitset::A => dbg.entry(format_args!("A")),
FancyBitset::B => dbg.entry(format_args!("B")),
FancyBitset::C => dbg.entry(format_args!("C")),
FancyBitset::D => dbg.entry(format_args!("D")),
FancyBitset::E => dbg.entry(format_args!("E")),
_ => dbg.entry(format_args!("{:#010X}", mask)),
};
}
dbg.finish()
}
} |
I recognize the temptation to code-golf the simplified example code snippets, but it's probably better to think of them as gesturing toward a general shape of problem rather than trying to optimize them as-is. |
I was just pointing out an alternative, not optimizing. |
We briefly discussed this in the libs API meeting yesterday, and are on board with adding this as an unstable feature. Feel free to open a tracking issue and open a PR to rust-lang/rust to add it as unstable. Please add open questions for the method names ( Thank you! |
I should also note that we also think your first alternative, the closure wrapping type, might be good to have in the standard library (in addition to the new methods on Debug{Struct, etc.}), although we think it should both implement I vaguely remember there was already another ACP for that, but I can't find it right now. |
Thanks! Tracking issue is rust-lang/rust#117729 and implementation PR (with your suggested changes) is rust-lang/rust#117730.
Sounds good to me. I've included this in the implementation PR as |
…viper Closure-consuming helper functions for `fmt::Debug` helpers ACP: rust-lang/libs-team#288 Tracking issue: rust-lang#117729
…cuviper Closure-consuming helper functions for `fmt::Debug` helpers ACP: rust-lang/libs-team#288 Tracking issue: rust-lang#117729
Rollup merge of rust-lang#117730 - jmillikin:fmt-debug-helper-fns, r=cuviper Closure-consuming helper functions for `fmt::Debug` helpers ACP: rust-lang/libs-team#288 Tracking issue: rust-lang#117729
Proposal
Problem statement
Implementing
fmt::Debug
for FFI types can be difficult because their layouts often don't match Rust conventions, for example by using a bitset for boolean properties or a(tag, union)
pair instead of an enumeration.Currently the formatting of these values can require creating auxiliary wrapper types that exist just to
impl Debug
for one particular field, which is verbose and unergonomic.Motivating examples or use cases
Example one: a bitset representing a set of boolean options. The bits should be formatted with names, and unknown bits should be formatted as numbers.
Example two: a union field conceptually only has one of its sub-fields populated at any given time, but figuring out which sub-field is valid requires inspecting the tag.
Solution sketch
Add methods to
DebugStruct
,DebugList
,DebugSet
, andDebugTuple
that make it easy to embed a formatting closure function directly into the mainimpl Debug
of a type.I'm ignoring
DebugMap
, but if the libs team thinks it should have similar functionality then i suggestkey_with()
andvalue_with()
rather than trying to have a double-closureentry_with()
.Also, I'm not married to the names, so you'd prefer
field_fmt()
or whatever then that's fine.They would be used like this:
Alternatives
Closure-wrapper function
This is more generic because it lets a closure be used in any place a
&dyn Debug
is expected, but it's slightly less flexible (F: Fn
rather thanF: FnOnce
) and the call site is more verbose due to required type annotations.Extension trait
Mostly I just wanted to see if it was possible. It is, but it's horrible.
trait Debug
quite reasonably uses&self
receivers, so the only way to getFnOnce
is to play games with aCell<Option<F>>
Links and related work
What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. 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:
The text was updated successfully, but these errors were encountered: