# 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 { 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> { let maybe_rc = MaybeRc::::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> { let maybe_arc = MaybeArc::::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.