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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// =============================================================================
// Copyright (c) 2025 - 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Derive macros for borrowing, policy-aware `qubit-redact` domain objects.
use TokenStream;
use Error;
use parse;
/// Derives the borrowing `qubit_redact::Redact` implementation.
///
/// Fields without an attribute intentionally use ordinary `Debug` formatting.
/// Sensitivity is downstream business-domain knowledge that the macro cannot
/// infer reliably from a field name or Rust type. Ordinary fields are the large
/// majority, so an explicit "not sensitive" attribute on every field would add
/// noise without adding knowledge. Downstream types must explicitly annotate
/// sensitive fields and review that classification when their model changes;
/// strict policy and inspection deliberately do not override this decision.
///
/// Supported field modes are:
///
/// - `#[redact(level = "low" | "medium" | "high" | "secret")]` masks every
/// supported scalar leaf while preserving recursive container shape. The
/// explicit level is final for text, inspection and Serde: runtime name
/// rules, sensitivity floors and strict mode cannot override it. Disabled
/// policy bypasses masking but retains resource limits. `RedactScalar`
/// newtypes are supported leaves; map keys remain ordinary unless separately
/// annotated;
/// - `#[redact(nested)]` delegates to nested `Redact` values;
/// - `#[redact(map)]` classifies text-keyed map values by key;
/// - `#[redact(json)]` recursively redacts supported JSON text or parsed Value
/// fields;
/// - `#[redact(skip)]` omits the field while redaction is enabled;
/// - `#[redact(keyed_by = key)]` classifies by a sibling textual key;
/// - `#[redact(map_key_level = "...", map_value_level = "...")]` assigns fixed
/// levels to map keys and values (the value level is optional);
/// - `#[redact(level = "...", display)]` selects lazy Display text for a
/// third-party scalar, without requiring Debug or ordinary Serialize.
///
/// Container options `#[redact(debug)]` and `#[redact(display)]` generate
/// policy-aware formatting implementations. `#[redact(serde)]` generates a
/// structured `serde::Serialize` implementation. Generated formatting writes
/// enabled-policy text directly for every completion state because it remains
/// confidentiality-safe;
/// callers that require completeness must use the runtime API and inspect its
/// summary instead.
///
/// Generated `Debug`, `Display`, and `Serialize` implementations intentionally
/// call `qubit_redact::Redactor::application_default()` at the start of every
/// formatting or serialization operation. They do not capture a policy when
/// the value is created. Replacing the process-wide application default affects
/// subsequent generated calls, and installing a disabled default deliberately
/// restores source values. Callers own authorization for that global debugging
/// escape hatch. Explicit runtime redactors, composers, and batches retain the
/// policy snapshot with which they were created.
///
/// # Parameters
///
/// * `input` - Compiler-provided derive input for a struct or enum.
///
/// # Returns
///
/// Generated implementations, or compile-error tokens for invalid input.
///
/// # Examples
///
/// ```
/// use qubit_redact::Redactor;
/// use qubit_redact_derive::Redact;
///
/// #[derive(Redact)]
/// struct Login {
/// user: String,
/// #[redact(level = "secret")]
/// password: String,
/// }
///
/// let login = Login {
/// user: "ada".to_owned(),
/// password: "raw-secret".to_owned(),
/// };
/// let output = Redactor::standard().redact_text(&login);
/// assert!(output.text().as_str().contains("ada"));
/// assert!(!output.text().as_str().contains("raw-secret"));
/// ```
/// Derives a scalar leaf capability for a one-field value object.
///
/// The inner field must be a primitive scalar or another `RedactScalar`.
/// No Debug, Display, or ordinary Serialize implementation is generated.
/// Select the sensitivity on the field that uses this value object.
///
/// # Parameters
///
/// * `input` - Compiler-provided single-field value-object declaration.
///
/// # Returns
///
/// Delegating scalar capability implementations, or compile-error tokens for
/// invalid shapes, attributes, or runtime paths.
///
/// # Examples
///
/// ```
/// use qubit_redact::Redactor;
/// use qubit_redact_derive::Redact;
/// use qubit_redact_derive::RedactScalar;
///
/// #[derive(RedactScalar)]
/// struct AccountId(u64);
///
/// #[derive(Redact)]
/// struct Event {
/// #[redact(level = "secret")]
/// account: AccountId,
/// }
///
/// let event = Event { account: AccountId(42) };
/// let output = Redactor::standard().redact_text(&event);
/// assert_eq!(output.text().as_str(), r#"Event { account: "<redacted>" }"#);
/// ```