qubit-redact-derive
qubit-redact-derive provides the #[derive(Redact)] procedural macro for
qubit-redact. It turns reviewed
field annotations into a policy-aware Redact::write_redacted implementation.
The derive never mutates the source value and exposes no mutable redaction API.
Installation
[]
= { = "0.5", = ["derive"] }
= "0.5"
Quick Start
use Redactor;
use Redact;
let value = Credentials ;
let output = standard.redact;
assert!;
assert!;
assert!;
Unmarked fields intentionally use ordinary Debug formatting. Whether a field
is sensitive is downstream business-domain knowledge that a derive macro cannot
reliably infer from its name or Rust type. Because ordinary fields are the vast
majority, requiring an explicit "not sensitive" attribute on every one would
create annotation noise without improving classification. Downstream types must
explicitly annotate sensitive fields and review new or changed fields. The
runtime's strict policy and inspection do not override this derive decision.
Field modes
| Attribute | Behavior |
|---|---|
| no attribute | Render ordinary Debug output. |
#[redact(level = "low"|"medium"|"high"|"secret")] |
Mask the field at the selected sensitivity. |
#[redact(skip)] |
Omit the field from the redacted output. |
#[redact(nested)] |
Delegate to the nested value's Redact implementation. |
#[redact(map)] |
Apply key-aware policy to supported text-keyed maps. |
#[redact(keyed_by = key)] |
Classify this field by a sibling text key, using the same policy semantics as one map entry. |
#[redact(json)] |
Apply recursive JSON-key redaction to supported JSON text values. |
#[redact(plain)], #[redact(no_mut)], and #[redact(require_explicit)] are
not part of the current contract. The macro supports named, tuple, and unit
structs and enum variants. #[redact(debug)], #[redact(display)], and
#[redact(serde)] are opt-in container attributes; Serde support requires the
runtime serde feature and a direct serde dependency. Their generated
implementations intentionally obtain the current
Redactor::application_default() snapshot at the start of every formatting or
serialization call; they do not capture policy when the value is created.
Replacing the process-wide default therefore affects subsequent calls.
keyed_by is available only on named fields. The referenced sibling key must
implement AsRef<str>, while the value uses the same recursive leaf capability
as level. Standard policies pass unknown keys through; configure sensitive
keys explicitly or use a stricter policy when unknown payload keys must be
masked.
The generated code resolves a direct qubit-redact dependency, including a
Cargo-renamed dependency. The runtime trait is intentionally small:
Safety boundary
Redaction protects only the boundary that uses Redactor, generated formatting,
or generated serialization. It does not erase the original value and cannot
protect unrelated logs or serialization paths. skip omits output but retains
the source field in memory. An unmarked field's pass-through behavior is an
intentional responsibility boundary, not a missing framework check.
Generated Debug and Display implementations write the confidentiality-safe
text produced by the enabled runtime policy even when a resource limit makes
the diagnostic incomplete. They do not force formatting callers to interpret a
completion reason that they cannot act on. Program logic that needs completeness
must call the runtime API and inspect its summary explicitly.
Installing a disabled application default is an intentional process-wide
debugging escape hatch and makes subsequent generated Debug, Display, and
Serialize calls restore source values. The framework does not authorize that
choice; callers own its environment controls, timing, and confidentiality
consequences. Explicit runtime redactors, composers, and batches keep the policy
snapshot with which they were created.
For parsed JSON that must remain borrowed and unchanged, use the runtime API
Redactor::redact_json_value(&serde_json::Value) or
Redactor::inspect_json_value(&serde_json::Value).
Learn More
See the English user guide, 中文用户手册, API documentation, and the runtime crate.
Testing
# Run tests with the default feature set
# Run tests with all declared features
# Project CI checks
# Check code coverage
License
Copyright (c) 2025 - 2026. Haixing Hu. All rights reserved.
Licensed under the Apache License, Version 2.0. See LICENSE for the full license text.
Contributing
Contributions are welcome. Please follow the Rust API guidelines, keep public
API documentation and tests current, and run ./align-ci.sh to format code and
./ci-check.sh to satisfy CI requirements before submitting a pull request.
Author
Haixing Hu - Qubit Co. Ltd.
Repository: https://github.com/qubit-ltd/rs-redact-derive