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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
use fmt;
use ManuallyDrop;
use Zeroize;
/// **English:**<br>
/// Owns a value whose [`Zeroize::zeroize`] method is called before it is dropped.
///
/// `Debug` and `Display` write the literal `[REDACTED]` rather than formatting `T`. Access is explicit through
/// [`Self::as_inner`], [`Self::expose_secret`], or [`Self::into_inner`]; this type implements
/// neither `Deref` nor serde `Serialize`. With `serde`, it implements `Deserialize` for
/// `T: serde::Deserialize<'de> + Zeroize`, taking ownership through [`Self::new`]. With
/// `serde_with`, `ExposeSecret` explicitly opts a field into plaintext output.
/// Internal deserialization errors are replaced with `failed to deserialize secret`;
/// independent format errors and logs from callers or custom implementations are not redacted.
/// This is not encryption. Successfully wrapped values are zeroized on drop, but input/output
/// buffers, parser temporaries, partially constructed or failed values, and other copies are not
/// covered. Cleanup during failed deserialization depends on the inner type and parser; serde's
/// contract cannot recover a partial `T` from an error. A caller-owned `zeroize::Zeroizing`
/// input buffer can reduce exposure, but cannot erase parser copies.
/// Cloning copies the inner value into another independently owned `Secret`. Equality delegates
/// to the inner type and does not promise constant-time comparison.
///
/// Zeroization follows `T`'s implementation and requires this wrapper's destructor to run;
/// it does not erase copies made elsewhere. [`Self::into_inner`] bypasses that destructor.
/// If `T::zeroize` panics, the inner value's destructor is not called by this wrapper.
/// `Send` and `Sync` depend on `T`; no synchronization is added.
///
/// Formatting hides the value; the closure below explicitly reads its length.
///
/// **日本語:**<br>
/// 所有する値を破棄する前に、その値の [`Zeroize::zeroize`] を呼び出すラッパーです。
///
/// `Debug` と `Display` は `T` を書式出力せず、リテラル `[REDACTED]` を出力します。値へのアクセスには
/// [`Self::as_inner`]、[`Self::expose_secret`]、[`Self::into_inner`] を明示的に使います。
/// `Deref` と serde の `Serialize` は実装しません。`serde` feature では
/// `T: serde::Deserialize<'de> + Zeroize` に対する `Deserialize` を実装し、[`Self::new`] で
/// 所有権を受け取ります。`serde_with` feature の `ExposeSecret` で、フィールドの
/// 平文出力を明示的に許可できます。内部型由来の復元エラーは `failed to deserialize secret` に
/// 置き換えますが、フォーマット側が独立に生成するエラーや呼び出し側・独自実装のログは秘匿しません。
/// 暗号化ではありません。正常に包んだ値は破棄時にゼロ化しますが、入出力バッファ、パーサーの
/// 一時値、構築途中・失敗時の値や別のコピーは対象外です。失敗時の後始末は内部型とパーサーに
/// 依存し、serde の契約ではエラーから構築途中の `T` を回収できません。入力バッファを
/// `zeroize::Zeroizing` で管理すると軽減できますが、パーサーのコピーは消去できません。
/// クローンは内包値を複製して別の `Secret` に所有させます。等値比較は内包型に
/// 委譲し、定数時間での比較を保証しません。
///
/// ゼロ化の範囲は `T` の実装に従い、このラッパーのデストラクターが実行される必要があります。
/// 別の場所に作られたコピーは消去しません。[`Self::into_inner`] はデストラクターを迂回します。
/// `T::zeroize` がパニックした場合、このラッパーは内包値のデストラクターを呼び出しません。
/// `Send` と `Sync` は `T` に依存し、同期機構は追加しません。
///
/// 書式出力は値を隠します。次のクロージャーでは長さを明示的に読み取ります。
///
/// # Example / 使用例
///
/// ```rust
/// use ddd_toolkit_core::Secret;
///
/// let secret = Secret::new(String::from("token"));
/// assert_eq!(format!("{secret:?}"), "[REDACTED]");
/// assert_eq!(format!("{secret}"), "[REDACTED]");
/// assert_eq!(secret.expose_secret(|value| value.len()), 5);
/// ```