sensitive-fmt
Derive Debug and Display for Rust structs while honoring sensitive field annotations. Designed for one job: keeping
PHI, PII, secrets, and tokens out of log lines.
I wrote this because none of the crates I could find (including my own safe-debug ) did exactly what I wanted as simply as I wanted to do it. This sensitive data redactor:
- derives both
DebugandDisplay - leans on existing implementations of both for non-primitive types, or lets you skip the field
- is as stupid and simple as I could make it
use ;
;
let p = Patient ;
assert_eq!;
assert_eq!;
Field attributes
One attribute, three modifiers (mutually exclusive):
| Attribute | Effect | required trait |
|---|---|---|
| (none) | normal Debug / Display |
Debug for SensitiveDebug, Display for SensitiveDisplay |
#[sensitive(redact)] |
writes REDACTED |
none |
#[sensitive(truncate = N)] |
writes ****<last N code points>, or REDACTED if value has fewer than N code points |
Display (in both derives) |
#[sensitive(skip)] |
writes <skipped> |
none |
Scope
- Named-field structs only. Tuple structs and enums fail at compile time with a clear message. Wrap the data in a named-field struct instead.
- Container types (
Option<T>,Vec<T>, etc.) are treated as opaque. If you have anOption<String>field you can'tDisplay-format directly, reach forredactorskip. - Generic structs are supported by adding trait bounds on the actual formatted field type. Plain fields require
DebugforSensitiveDebugorDisplayforSensitiveDisplay;truncatealways requiresDisplay;redactandskipdo not add formatting bounds. no_stdcompatible. Requiresallocfor thetruncatemodifier.- Minimum supported Rust version: 1.88.0.
- Truncate counts code points, not graphemes.
"café"is 4 code points.
Why not [other crate]?
| Crate | Debug | Display | Truncate | Why this crate exists |
|---|---|---|---|---|
veil |
yes | no | head + tail of *s |
no Display, no last-N |
redactable |
yes | yes | named policies (Token / PII / …) | grew slog/tracing/json features |
secrecy / redact |
wrapper | wrapper | none | wrapper-type model, not derives |
safe-debug |
yes | no | n/a | requires the facet ecosystem |
License
MIT OR Apache-2.0