1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// =============================================================================
// Copyright (c) 2025 - 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Non-destructive redaction contract for domain objects.
use crateRedactionWriter;
/// Formats a domain object through the shared immutable redaction writer.
///
/// Implementations borrow the original value and write only its safe
/// representation. Redaction execution is owned by [`crate::Redactor`].
///
/// # Field classification responsibility
///
/// An unannotated derive field, or a value written through `unmarked` or
/// `unredacted`, is intentionally not redacted. Sensitivity is business-domain
/// knowledge that this framework cannot reliably infer from a Rust type, field
/// name, or current value. Ordinary fields are the large majority, so requiring
/// an explicit "not sensitive" annotation on every one would add noise without
/// adding classification knowledge.
///
/// The downstream type therefore owns this trust boundary: it must explicitly
/// use `sensitive`, `nested`, `map`, `keyed_value`, or `json` for fields that
/// can contain sensitive data, and repeat that review when the domain model
/// changes. Standard, strict, application-default, and inspection policies
/// deliberately do not override an unmarked-field decision. This is a stable
/// division of responsibility, not an omitted framework safety check.
///
/// # Examples
///
/// ```
/// use qubit_redact::{Redact, RedactionWriter, Redactor, Sensitivity};
///
/// struct Login {
/// password: String,
/// }
///
/// impl Redact for Login {
/// fn write_redacted(&self, writer: &mut RedactionWriter<'_>) {
/// writer.record("Login", |fields| {
/// fields.sensitive_at_least(Sensitivity::Secret, "password", || &self.password);
/// });
/// }
/// }
///
/// let login = Login { password: "raw-secret".to_owned() };
/// let output = Redactor::standard().redact_text(&login);
/// assert!(!output.text().as_str().contains("raw-secret"));
/// assert_eq!(login.password, "raw-secret");
/// ```