-
Notifications
You must be signed in to change notification settings - Fork 0
/
README.md.contested
56 lines (45 loc) · 1.44 KB
/
README.md.contested
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
# MaybeRc
This library provides a method of creating circular reference counted
dependencies when creation of the nested objects can fail (return Result)
or requires async function.
## Details
Usually `Rc::new_cyclic` can be used:
```rust
fn new() -> Rc<Self> {
Rc::new_cyclic(|weak| {
let child = Child::new(weak);
Self {
child,
}
})
}
```
But what to do in cases when `Child::new` is async or returns an `Option` or `Result`?
This is the problem that MaybeRc tries to solve:
```rust
async fn new() -> Option<Rc<Self>> {
let maybe_rc = MaybeRc::<Self>::new();
let weak = maybe_rc.downgrade();
let child = Child::new(weak).await?;
Some(maybe_rc.materialize(Self {
child,
}))
}
```
Same approach can be used for `Arc` types with `MaybeArc` implementation:
```rust
async fn new() -> Option<Arc<Self>> {
let maybe_arc = MaybeArc::<Self>::new();
let weak = maybe_arc.downgrade();
let child = Child::new(weak).await?;
Some(maybe_arc.materialize(Self {
child,
}))
}
```
## Unsafe Assumptions
Under the hood `MaybeRc` and `MaybeArc` use some unsafe *magic* to implement this behavior.
This *magic* makes some assumptions:
1. all strong references collectively "hold" a single weak reference count
2. we can restore strong reference even when strong counter is zero by calling `increment_strong_count`
Unless these assumptions are broken library will behave correctly.