Format number as blank when it's zero

I mimic Windows directory out display using something like:

dir.push_str(&format!("{:8}{m:>2}/{d:>2}/{y:4}  {h:>2}:{mm:02} {}M    {:>16} ",' ', pm, metadata.len()));

It works stunning, however if I compare a real dir command display:

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        12/25/2024   5:15 PM                .cargo
-a----        12/29/2024   7:24 PM            100 .gitconfig

There is no number for a directory length, but my format string shows it as 0. How to solve the problem in the shortest and smart way? I suspect also, that I should display zero for empty files. metadata.is_dir() is already stored in some variable.

I wouldn't hide the size of an empty file. It really should be shown as 0, since logically that's what it is. A directory, on the other hand, doesn't really have a size of its own.

So I'd just use a simple if is_dir {...} else {...} instead of trying to overengineer it.

Also, you can use write!(dir, ...) instead of dir. push_str(&format!(...)); it's tidier and much more efficient.

It's a good tip using write!(dir, I need to get it my tip chest.

Shortest, perhaps not if you only need it in one place, but you can do something like

struct EntryLen<'a>(&'a Metadata);

impl fmt::Display for EntryLen<'_> {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.0.is_dir() {
            "".fmt(fmt)
        } else {
            self.0.len().fmt(fmt)
        }
    }
}

// ...

format!(
    "{:8}{m:>2}/{d:>2}/{y:4}  {h:>2}:{mm:02} {}M    {:>16} ",
    ' ', 
    pm, 
    EntryLen(&metadata),
);
1 Like

Is there a particular benefit to this over simply Ok(())? Intuitability, perhaps?

1 Like

Honoring formatting directives such as the width. Modified example.

2 Likes

Ah, I forgot it still applies formatting to empty strings.

Thank you, it works like a charm. Funny thing I found that Rust and Windows API give inconsistent results in a timestamp of file:

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         4/11/2025   7:18 PM                .dat
d-----          4/5/2025   4:12 PM                .fak
d-----          6/6/2025   4:17 PM                install
d-----          6/7/2025  11:31 AM                resource
-a----        12/26/2024   8:11 PM             14 .home
-a----          6/5/2025   3:04 PM            309 bee-term.7b
-a----          6/6/2025   4:17 PM           1793 bee.7b
-a----          5/3/2025   1:02 PM          14499 crossref.rs
-a----          6/2/2025   6:27 PM          57105 docgi.rs
-a----          6/1/2025   6:38 PM        9611709 rds-1.15.00.zip
-a----          6/2/2025   6:27 PM          10411 README.md
-a----          6/5/2025   3:06 PM        6114653 rustcgi.exe
-a----          1/5/2025   4:37 PM           5197 search.rs
-a----         4/11/2025   7:57 PM        5576193 snapurl.exe
-a----          6/7/2025  12:08 PM        5841677 terminal.exe
-a----          6/7/2025  12:09 PM          46114 terminal.rs
-a----          6/1/2025   6:36 PM        5475049 webcgi.exe

This result is Windows API produced, however Rust code produces a slight difference:

                 4/11/2025   7:18 PM                .dat
d-----         4/ 5/2025   4:12 PM                .fak
-a----        12/26/2024   9:11 PM             14 .home
-a----         6/ 5/2025   3:04 PM            309 bee-term.7b
-a----         6/ 6/2025   4:17 PM           1793 bee.7b
-a----         5/ 3/2025   1:02 PM          14499 crossref.rs
-a----         6/ 2/2025   6:27 PM          57105 docgi.rs
d-----         6/ 6/2025   4:17 PM                install
-a----         6/ 1/2025   6:38 PM        9611709 rds-1.15.00.zip
-a----         6/ 2/2025   6:27 PM          10411 README.md
d-----         6/ 7/2025  11:31 AM                resource
-a----         6/ 5/2025   3:06 PM        6114653 rustcgi.exe
-a----         1/ 5/2025   5:37 PM           5197 search.rs
-a----         4/11/2025   7:57 PM        5576193 snapurl.exe
-a----         6/ 7/2025  12:10 PM        5841677 terminal.exe
-a----         6/ 7/2025  12:09 PM          46114 terminal.rs
-a----         6/ 1/2025   6:36 PM        5475049 webcgi.exe

I tried created(), acessed(), and modified() results, and the former gives the best match, but still not exact. My theory that Windows apples DST hour accordingly when the file was modified, but my code to all timestamps regardless when they happened. I intentionally do not apply sorting, but leading blank in a day number probably should be eliminated.