1use crate::{
2 deps_list::{DepsList, DepsListGetMut, DepsListGetRef, DepsListRemove},
3 injector::{
4 containers::{
5 ConstructorFactoryContainer, FactoryContainer, RefConstructorFactoryContainer,
6 RefFactoryContainer, SingletonContainer,
7 },
8 factories::{ConstructorFactory, Factory, RefFactory},
9 },
10};
11use core::{convert::Infallible, marker::PhantomData};
12
13pub struct CurrentScope(Infallible);
15pub struct ParentScope<Scope>(PhantomData<Scope>, Infallible);
17
18pub struct DependencyContainer<Parent, Scope> {
24 pub(crate) parent: Parent,
25 pub(crate) scope: Scope,
26}
27
28impl Default for DependencyContainer<(), ()> {
29 fn default() -> Self {
30 Self::new(())
31 }
32}
33
34impl<Parent> DependencyContainer<Parent, ()> {
35 pub fn new(parent: Parent) -> Self {
37 Self { parent, scope: () }
38 }
39}
40
41impl<Parent, Scope> DependencyContainer<Parent, Scope>
42where
43 Scope: DepsList,
44{
45 pub fn with_singleton<T>(
47 self,
48 singleton: T,
49 ) -> DependencyContainer<Parent, Scope::PrependedWith<SingletonContainer<T>>> {
50 DependencyContainer {
51 parent: self.parent,
52 scope: self.scope.prepend(SingletonContainer(singleton)),
53 }
54 }
55
56 pub fn with_factory<F>(
58 self,
59 factory: F,
60 ) -> DependencyContainer<Parent, Scope::PrependedWith<FactoryContainer<F, F::Result>>>
61 where
62 F: Factory,
63 {
64 DependencyContainer {
65 parent: self.parent,
66 scope: self.scope.prepend(FactoryContainer(factory, PhantomData)),
67 }
68 }
69
70 pub fn with_ref_factory<'a, F>(
72 self,
73 factory: F,
74 ) -> DependencyContainer<Parent, Scope::PrependedWith<RefFactoryContainer<F, F::Result<'a>>>>
75 where
76 F: RefFactory,
77 {
78 DependencyContainer {
79 parent: self.parent,
80 scope: self
81 .scope
82 .prepend(RefFactoryContainer(factory, PhantomData)),
83 }
84 }
85
86 pub fn with_constructor_factory<T>(
88 self,
89 ) -> DependencyContainer<Parent, Scope::PrependedWith<ConstructorFactoryContainer<T>>>
90 where
91 T: ConstructorFactory,
92 {
93 DependencyContainer {
94 parent: self.parent,
95 scope: self.scope.prepend(ConstructorFactoryContainer(PhantomData)),
96 }
97 }
98
99 pub fn with_ref_constructor_factory<T>(
102 self,
103 ) -> DependencyContainer<Parent, Scope::PrependedWith<RefConstructorFactoryContainer<T>>> {
104 DependencyContainer {
105 parent: self.parent,
106 scope: self
107 .scope
108 .prepend(RefConstructorFactoryContainer(PhantomData)),
109 }
110 }
111}
112
113impl<Parent, Scope, T, Idx> DepsListRemove<T, (CurrentScope, Idx)>
114 for DependencyContainer<Parent, Scope>
115where
116 Scope: DepsListRemove<T, Idx>,
117{
118 type Remainder = DependencyContainer<Parent, Scope::Remainder>;
119
120 fn remove(self) -> (T, Self::Remainder) {
121 let (removed, scope_remainder) = self.scope.remove();
122 (
123 removed,
124 DependencyContainer {
125 parent: self.parent,
126 scope: scope_remainder,
127 },
128 )
129 }
130}
131
132impl<Parent, Scope, T, Idx, Subscope> DepsListRemove<T, (ParentScope<Subscope>, Idx)>
133 for DependencyContainer<Parent, Scope>
134where
135 Parent: DepsListRemove<T, (Subscope, Idx)>,
136{
137 type Remainder = DependencyContainer<Parent::Remainder, Scope>;
138
139 fn remove(self) -> (T, Self::Remainder) {
140 let (removed, parent_remainder) = self.parent.remove();
141
142 (
143 removed,
144 DependencyContainer {
145 parent: parent_remainder,
146 scope: self.scope,
147 },
148 )
149 }
150}
151
152impl<Parent, Scope, T, Idx> DepsListGetRef<T, (CurrentScope, Idx)>
153 for DependencyContainer<Parent, Scope>
154where
155 Scope: DepsListGetRef<T, Idx>,
156{
157 fn get(&self) -> &T {
158 self.scope.get()
159 }
160}
161
162impl<Parent, Scope, T, Idx, Subscope> DepsListGetRef<T, (ParentScope<Subscope>, Idx)>
163 for DependencyContainer<Parent, Scope>
164where
165 Parent: DepsListGetRef<T, (Subscope, Idx)>,
166{
167 fn get(&self) -> &T {
168 self.parent.get()
169 }
170}
171
172impl<Parent, Scope, T, Idx> DepsListGetMut<T, (CurrentScope, Idx)>
173 for DependencyContainer<Parent, Scope>
174where
175 Scope: DepsListGetMut<T, Idx>,
176{
177 fn get_mut(&mut self) -> &mut T {
178 self.scope.get_mut()
179 }
180}
181
182impl<Parent, Scope, T, Idx, Subscope> DepsListGetMut<T, (ParentScope<Subscope>, Idx)>
183 for DependencyContainer<Parent, Scope>
184where
185 Parent: DepsListGetMut<T, (Subscope, Idx)>,
186{
187 fn get_mut(&mut self) -> &mut T {
188 self.parent.get_mut()
189 }
190}