reifydb_core/util/ioc/
resolve_rc.rs1use std::{
5 any::{Any, type_name},
6 cell::OnceCell,
7 rc::Rc,
8};
9
10use reifydb_type::{Result, diagnostic::internal, error};
11
12use super::IocContainer;
13
14pub struct LazyResolveRc<T> {
17 inner: Rc<LazyResolveInner<T>>,
18}
19
20struct LazyResolveInner<T> {
22 value: OnceCell<T>,
23}
24
25#[allow(dead_code)]
26impl<T: Clone> LazyResolveRc<T> {
27 pub fn new() -> Self {
29 Self {
30 inner: Rc::new(LazyResolveInner {
31 value: OnceCell::new(),
32 }),
33 }
34 }
35
36 pub fn get_or_resolve(&self, ioc: &IocContainer) -> Result<&T>
40 where
41 T: Clone + Any + Send + Sync + 'static,
42 {
43 if let Some(value) = self.inner.value.get() {
44 return Ok(value);
45 }
46
47 let resolved = ioc.resolve::<T>()?;
49 match self.inner.value.set(resolved) {
50 Ok(()) => {
51 self.inner.value.get().ok_or_else(|| {
53 error!(internal(format!(
54 "Failed to get value after setting in OnceCell for type {}",
55 type_name::<T>()
56 )))
57 })
58 }
59 Err(_) => {
60 Err(error!(internal(format!(
63 "Failed to set value in OnceCell for type {}",
64 type_name::<T>()
65 ))))
66 }
67 }
68 }
69
70 #[allow(dead_code)]
72 pub fn get(&self) -> Option<&T> {
73 self.inner.value.get()
74 }
75
76 #[allow(dead_code)]
78 pub fn is_resolved(&self) -> bool {
79 self.inner.value.get().is_some()
80 }
81}
82
83impl<T: Clone> Clone for LazyResolveRc<T> {
84 fn clone(&self) -> Self {
85 Self {
86 inner: Rc::clone(&self.inner),
87 }
88 }
89}
90
91impl<T: Clone> Default for LazyResolveRc<T> {
92 fn default() -> Self {
93 Self::new()
94 }
95}