use std::mem::MaybeUninit;
use std::{rc::Rc, rc::Weak};
pub fn rc_new_cyclic_fallible<T, E, F>(f: F) -> Result<Rc<T>, E>
where
F: FnOnce(&Weak<T>) -> Result<T, E>,
{
let mut result: Result<(), E> = Ok(());
let maybe_uninit_rc = Rc::<MaybeUninit<T>>::new_cyclic(|weak_uninit| unsafe {
let weak: &Weak<T> = core::mem::transmute(weak_uninit);
match f(weak) {
Ok(t) => MaybeUninit::<T>::new(t),
Err(err) => {
result = Err(err);
MaybeUninit::<T>::uninit()
}
}
});
result?;
let converted: Rc<T> = unsafe { core::mem::transmute(maybe_uninit_rc) };
Ok(converted)
}