hh_slog::FmtN - prints first N items of slice/set
commitee0ab96431fb4eace8d79a0adcb95dae026026b4
authorLucian Wischik <ljw@meta.com>
Sat, 19 Nov 2022 15:17:59 +0000 (19 07:17 -0800)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Sat, 19 Nov 2022 15:17:59 +0000 (19 07:17 -0800)
treebf389bafba745bda3a1a9e5ed956699d412fa0e3
parent711586ffb70b3952c7888bd6df73d00f5a56107f
hh_slog::FmtN - prints first N items of slice/set

Summary:
In hh_server logging, we commonly want to print the first few items of a list/set. For instance, if there are watchman file changes, we like to print the first 5 of them. If we determine that symbols have changed, we'd like to print the first few. Once we calculate the fanout, we'd like to print the first few files.

It's surprisingly powerful to just print the first 3 or 4 or 5! Usually in rage reports, there's just a single file that changed, and a handful of symbols changed in it, and seeing those printed out is powerful. On the other hand, when there are hundreds or thousands of items, it just about never benefits us to see the full list, but we usually do want to know the size of the list.

This diff introduces FmtN:
```
let names: Vec<String> = ...;
eprintln!("strings: {}", FmtN::slice(3, &names));
// strings: [none]
// strings: alpha
// strings: alpha, beta
// strings: alpha, beta, gamma
// strings: alpha, beta, gamma, ... [4 total]
// strings: alpha, beta, gamma, ... [5 total]

let files: BTreeSet<PathBuf> = ...;
eprintln!("pathbufs: {:?}", FmtN::set(5, &files));
// similarly, but with set instead of slice
```

I put this helper in hh_slog because, well, logging is the only realistic scenario for FmtN. (I could move it into a crate of its own if you think that's better).

I implemented FmtN<T> to support Display and Debug, because some things like `Vec<String>` can be display-printed, and others like `Vec<PathBuf>` must be debug-printed, and I've needed both.

Design: I wrote this to only work with slice and set. That's because displaying ", ... [total M]" is important, and therefore I needed something which had an O(1) length operation, and I could get that for slice and set.

Implementation: I wrote this to eagerly gather the first N elements into a vec. I tried to write it with an iterator but failed. I figure that's okay; in practice we only use this for a small number of elements.

Reviewed By: edwinsmith

Differential Revision: D41364872

fbshipit-source-id: 2c79295a94f9d9087486cd03dd9dd04fa0b27671
hphp/hack/src/utils/hh_slog/cargo/hh_slog/Cargo.toml
hphp/hack/src/utils/hh_slog/hh_slog.rs