-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
format-dynamic-fill #3394
format-dynamic-fill #3394
Conversation
Co-authored-by: Josh Triplett <[email protected]>
This seems relatively straightfoward. It adds a little bit overhead to std::fmt::write to be able to support this feature, but that can probably be kept to a minimum. For context, there are currently eight formatting options: width, precision, fill, alignment, sign, alternate, zero padding and debug hex. Only the first two can be picked dynamically. With the proposed change, the first three become dynamic:
There is some overhead involved in allowing an option to be dynamic, so I think it makes sense to only do this for the |
Perhaps we should (also) add a way to create a Formatter. |
@rfcbot merge |
Team member @m-ou-se has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
I asked that on zulip as well: https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Formatter.20construction.20without.20need.20for.20hardcoded.20string/near/338148530 |
Yes, but turns out, doing that for all combinations will still create a bunch of code (and actually make this otherwise very small crate, slower to compile than I had hoped) https://github.com/ModProg/interpolator/blob/577d7e4365818466203ad94a4228bfd4b1aff512/src/fmt/display.rs |
Are there examples of a use case in which this would be used for real? The only example invocation in the RFC is with non-dynamic fill characters ( @rfcbot concern needs more compelling motivation |
My use case is implementing a runtime version of For my use case this isn't the ideal solution (I'd prefer being able to create a |
I feel that the As I see it:
So I would say let's skip this feature and directly go to Formatters that can be populated with a dynamic set of configuration without using format_args syntax. @rfcbot concern expose Formatter construction instead of this Directly adding impl<'a> Formatter<'a> {
pub fn set_fill(&mut self, fill: char) {
self.fill = fill;
}
} That is how C++ iostream / iomanip work (https://en.cppreference.com/w/cpp/io/manip). For example Instead maybe this kind of API: // core::fmt
impl<'a> Formatter<'a> {
pub fn with_fill<'b>(&'b mut self, fill: char) -> Formatter<'b>
where
'a: 'b,
{
Formatter {
fill,
flags: self.flags,
...
buf: &mut *self.buf, // reborrow with shorter lifetime
}
}
} // user code
struct DynamicFill<D> {
fill: char,
delegate: D,
}
impl<D: Display> Display for DynamicFill<D> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.delegate, &mut formatter.with_fill(self.fill))
}
} or a more general builder: impl Formatter<'_> {
pub fn builder() -> FormatterBuilder;
}
impl FormatterBuilder {
pub fn fill(&mut self, fill: char) -> &mut Self;
pub fn build(&mut self, /*a `&'a mut dyn Write` arg goes either here or builder()*/) -> Formatter<'a>;
} let mut buf = String::new();
let formatter = fmt::Formatter::builder()
.fill(ch)
.build(&mut buf);
thing.fmt(&mut formatter)?; |
One case where I've wanted dynamic fill is implementing a C printf by mapping as much as possible to rust fmt, but that's pretty niche (I also don't have the code on hand). It would also be well-supported by @dtolnay's suggestion. |
Yeah, this RFC arose more or less of the feeling that getting access to formatter construction/modification is something that will probably not happen in the near future, and this seamed more achievable. I'm very much in favor of having access to the formatter (although this would mean I wasted a lot of time implementing interpolator the way I did 😄 ) |
In that case, it seems Formatter construction is the preferred route. So let's go in that direction instead. :) @rfcbot cancel |
@m-ou-se proposal cancelled. |
If there is a path forward for that, I'll happily agree. |
I also would love runtime setting of |
@rfcbot fcp close Next step: we can equate #3394 (comment) to an approved ACP, so next step would be prototype it in a PR. Maybe RFC if we need to argue about whether a builder is needed. My preference is no separate builder type if possible. |
Team member @dtolnay has proposed to close this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
Rendered