Skip to content

Commit 91cdba1

Browse files
committed
1. Updated documentation
1 parent 4ee5256 commit 91cdba1

File tree

2 files changed

+290
-52
lines changed

2 files changed

+290
-52
lines changed

README.md

Lines changed: 146 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ A safe version of ManuallyDrop with various features and options to track undefi
1010

1111
### 1. easy
1212

13-
```rust
13+
```should_panic
1414
use SafeManuallyDrop::ManuallyDrop;
1515
use std::ops::Deref;
1616
@@ -53,7 +53,90 @@ fn main() {
5353
}
5454
```
5555

56-
### 2. hook
56+
### 2. EasyStruct
57+
58+
```rust
59+
// 1. In production code, it is recommended to use AutoSafe instead of AlwaysSafe,
60+
// this will eliminate unnecessary checks in the release build, but leave
61+
// them in the test build.
62+
//
63+
// 2. It is generally recommended to use Panic or Abort as a trigger for undefined behavior.
64+
//
65+
use SafeManuallyDrop::AlwaysSafePanicManuallyDrop as ManuallyDrop;
66+
67+
#[derive(Default, Debug)]
68+
struct ControlDrop(usize);
69+
70+
// Properly created and validated MyLogicData structure.
71+
#[derive(Default)]
72+
struct MyLogicData {
73+
data: ManuallyDrop<ControlDrop>
74+
}
75+
76+
impl MyLogicData {
77+
/// Exceptional logic. As a result, the original value will always be returned.
78+
pub fn ignore_mylogic_and_getdata(mut self) -> ControlDrop {
79+
// Note that you can only `take` once, any further operation with
80+
// ManuallyDrop will cause a panic.
81+
let data = unsafe {
82+
ManuallyDrop::take(&mut self.data)
83+
};
84+
85+
// ManuallyDrop::forget analog forget(self).
86+
ManuallyDrop::forget(self);
87+
88+
/*
89+
data logic
90+
*/
91+
92+
data
93+
}
94+
}
95+
96+
impl Drop for MyLogicData {
97+
fn drop(&mut self) {
98+
/*
99+
def logic
100+
*/
101+
println!("MyLogicData, indata: {:?}", self.data);
102+
103+
/*
104+
Notification
105+
1. `ManuallyDrop` always requires it to be freed when it is no longer needed.
106+
2. Once `ManuallyDrop` is freed, you will not be able to read data from it
107+
3. You cannot drop `ManuallyDrop` twice.
108+
...
109+
110+
You can remove the `unsafe` flags if you don't use the `always_compatible_stdapi` flag.
111+
*/
112+
unsafe {
113+
ManuallyDrop::drop(&mut self.data);
114+
}
115+
}
116+
}
117+
118+
fn main() {
119+
{
120+
// run my logic
121+
let indata = MyLogicData::default();
122+
drop(indata);
123+
124+
// This case will just make the logic default by executing the code in drop.
125+
}
126+
{
127+
// ignore_mylogic
128+
let indata = MyLogicData::default();
129+
let cd_data = indata.ignore_mylogic_and_getdata();
130+
131+
println!("ignore_mylogic: {:?}", cd_data);
132+
133+
// In this case, the standard reset logic is eliminated and another
134+
// specific principle is used, which is embedded in the function with data return.
135+
}
136+
}
137+
```
138+
139+
### 3. hook
57140

58141
```rust
59142
use std::ops::Deref;
@@ -93,7 +176,7 @@ fn main() {
93176
}
94177
```
95178

96-
### 3. counter
179+
### 4. counter
97180

98181
```rust
99182
// Let me remind you that CounterManuallyDrop by behavior allows undefined
@@ -155,12 +238,56 @@ fn main() {
155238
}
156239
```
157240

158-
# cargo.toml -> features
241+
### 1. PlugAndPlay (Minimal, Panic)
242+
```rust,ignore
243+
[dependencies.SafeManuallyDrop]
244+
version = "1.0.3"
245+
default-features = false
246+
features = [
247+
"always_check_in_case_debug_assertions",
248+
249+
#"always_compatible_stdapi",
250+
251+
"support_panic_trig",
252+
"always_deftrig_panic"
253+
]
254+
```
255+
256+
### 2. PlugAndPlay (Minimal, Abort)
257+
```rust,ignore
258+
[dependencies.SafeManuallyDrop]
259+
version = "1.0.3"
260+
default-features = false
261+
features = [
262+
"always_check_in_case_debug_assertions",
263+
264+
#"always_compatible_stdapi",
265+
266+
"support_abort_trig",
267+
"always_deftrig_abort"
268+
]
269+
```
159270

271+
### 3. PlugAndPlay (Minimal, Hook)
272+
```rust,ignore
273+
[dependencies.SafeManuallyDrop]
274+
version = "1.0.3"
275+
default-features = false
276+
features = [
277+
"always_check_in_case_debug_assertions",
278+
279+
#"always_compatible_stdapi",
280+
281+
"support_hookfn_trig",
282+
"always_deftrig_hookfn"
283+
]
160284
```
285+
286+
# cargo.toml -> features
287+
288+
```rust,ignore
161289
// Flags:
162290
//
163-
164291
// ManuallyDrop and AutoManuallyDrop are always type safe and are automatically
165292
// checked on use if the debug_assertions flag is enabled (the flag is automatically
166293
// enabled if test build, debug build, or env: CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS=true).
@@ -172,7 +299,7 @@ fn main() {
172299
// regardless of external flags.
173300
//
174301
// (Also, AlwaysSafeManuallyDrop is always checked for safety when it is used, regardless of the flags.)
175-
// "always_safe_manuallydrop",
302+
//"always_safe_manuallydrop",
176303
177304
// Enable additional internal checks of the SafeManuallyDrop library when
178305
// the debug_assertions flag is enabled (does not depend on the always_check_in_case_debug_assertions
@@ -181,8 +308,8 @@ fn main() {
181308
//
182309
// "allow_fullinternal_debug_assertions",
183310
184-
// Preserve unsafe fn flags even if functions are safe
185-
// (may be required for additional compatibility with the standard API)
311+
# Preserve unsafe fn flags even if functions are safe
312+
# (may be required for additional compatibility with the standard API)
186313
"always_compatible_stdapi",
187314
188315
// Always create a modular table of library flags used in the build.
@@ -191,13 +318,16 @@ fn main() {
191318
192319
// Trigs:
193320
//
194-
195321
// Ability to determine if an empty loop trigger has been executed.
196322
"support_istrig_loop",
197323
198324
// Support for PanicManuallyDrop, in case of undefined behavior
199-
// of PanicManuallyDrop there will be a panic.
200-
"support_panic_trig",
325+
// of ManuallyDrop there will be a panic.
326+
"support_panic_trig",
327+
328+
// Support for AbortManuallyDrop, in case of undefined behavior
329+
// of ManuallyDrop there will be a abort. (Note that this feature requires std.)
330+
//"support_abort_trig",
201331
202332
// HookManuallyDrop support, in case of undefined HookManuallyDrop behavior,
203333
// the hook function will be called.
@@ -211,9 +341,13 @@ fn main() {
211341
// cause a panic in case of undefined behavior.
212342
//"always_deftrig_panic",
213343
344+
// The behavior for the simple AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop type will always
345+
// cause a abort in case of undefined behavior.
346+
//"always_deftrig_abort",
347+
214348
// The behavior for the simple AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop type will always
215349
// call the hook function in case of undefined behavior.
216-
//"always_deftrig_hookfn",
350+
"always_deftrig_hookfn",
217351
218352
// The behavior for the simple AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop type will always call
219353
// the +1 counter function in case of undefined behavior.
@@ -222,21 +356,6 @@ fn main() {
222356
// The behavior for the simple type AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop will always call
223357
// the eternal loop function in case of undefined behavior.
224358
//"always_deftrig_loop"
225-
226-
// INFO:
227-
// If the behavior for the general AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop is not fixed,
228-
// the behavior will be determined according to the following scheme:
229-
//
230-
// always_deftrig_panic not exists AND
231-
// always_deftrig_hookfn not exists AND
232-
// always_deftrig_count not exists AND
233-
// always_deftrig_loop not exists THEN
234-
//
235-
// support_hookfn_trig -> Hook, else:
236-
// support_panic_trig -> Panic, else:
237-
// support_count_trig -> Count, else:
238-
// Loop
239-
//
240359
```
241360

242361
# License

0 commit comments

Comments
 (0)