Skip to content
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!() ignores precision while formatting Debug #55584

Open
imp opened this issue Nov 1, 2018 · 7 comments
Open

format!() ignores precision while formatting Debug #55584

imp opened this issue Nov 1, 2018 · 7 comments
Labels
T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@imp
Copy link

imp commented Nov 1, 2018

The precision field is ignored when formatting/printing Debug representation. Apparently, it is honored when formatting Display representation.

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2015&gist=516b0c6222b4b351b69e45c15943821b

@ExpHP
Copy link
Contributor

ExpHP commented Dec 20, 2018

I'd say this is not a bug.

Debug is for printing data structures, not strings, and it should not be treated by formatting flags as a string. And as a matter of fact, impl Debug for f64 currently does respect the precision, and does what one would expect for a floating point number: (which is different from what you want!)

// The behavior proposed here would change this to "0.12343"
assert_eq!(format!("{:.7?}", 0.1234321111), "0.1234321");

If anything, I feel like {:.7?} should do a full debug printout, recursively setting the precision for all floating point numbers. This would be consistent with existing syntax for recursively formatting hexadecimal:

assert_eq!(format!("{:02x?}", b"Foo\0"), "[46, 6f, 6f, 00]");

(though once again I find myself frustrated that there is no Fixed formatting trait for what is currently impl Display for f64. The syntax for recursively setting fixed precision on homogenous data structures ought to be {:.7f?} for clarity)

@ExpHP
Copy link
Contributor

ExpHP commented Dec 27, 2018

If anything, I feel like {:.7?} should do a full debug printout, recursively setting the precision for all floating point numbers.

Turns out it already does this.

#[derive(Debug, Clone)]
struct Wrapper(f64);

fn main() {
    println!("{:.7?}", vec![Wrapper(1.0); 4]);
}
[Wrapper(1.0000000), Wrapper(1.0000000), Wrapper(1.0000000), Wrapper(1.0000000)]

@estebank estebank added A-macros-2.0 Area: Declarative macros 2.0 (#39412) T-lang Relevant to the language team, which will review and decide on the PR/issue. and removed A-macros-2.0 Area: Declarative macros 2.0 (#39412) labels Jan 19, 2019
@estebank
Copy link
Contributor

Similar case from #55749.

#[derive(Debug)]
enum MyEnum {
    AB,
}

fn main() {
    let value = MyEnum::AB;
    println!("[{: <3?}]", value); // The result is `[AB]`
                                  // while I expected that the result is `[AB ]`.
}

@ExpHP
Copy link
Contributor

ExpHP commented Jan 19, 2019

@estebank that also already does something: It recursively sets the width, alignment and fill for integers and floats.

assert_eq!(format!("{: >4?}", [1.0, 2.0]), "[ 1.0,  2.0]");
assert_eq!(format!("{: <4?}", [1.0, 2.0]), "[1.0 , 2.0 ]");
    
// Specific use case
assert_eq!(format!("{:02x?}", [1, 2]), "[01, 02]");

Debug formatting is not string formatting!

@fan-tom
Copy link

fan-tom commented May 24, 2019

I also get stuck with precision in debug formatting, I want it because sometimes print is tooo long and I want to just, for example, see what is top-level enum variant, Is there any way to set precision for whole debug output, something like {{:?}:.<prec>}}? Here I want to get debug print and take only first characters. I know I can hand-write Debug implementation, but I'm too lazy)

@dimo414
Copy link
Contributor

dimo414 commented Dec 8, 2019

So it sounds like width and precision are working as intended for ? debug formatting, but I don't see this behavior discussed in https://doc.rust-lang.org/std/fmt/ - is there somewhere else this is documented?

@folex
Copy link
Contributor

folex commented Mar 25, 2021

As @fan-tom I, too, want to limit the length of a debug-printed output for some structure that can contain a lot of data inside while I only care about the first part of it.

Sometimes derivative crate helps by allowing me to ignore a few fields. But sometimes it is not enough. For example, because there's only one field, and I want to see it, but still limit its length. Or it is an array.

So currently I work around that (in tests) like this:

log::warn!("foo {:.100}", format!("{:?}", foo));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants