1use std::any::Any;
2use std::marker::PhantomData;
3use std::sync::Arc;
4
5use crate::injection_context::InjectionContext;
6use crate::*;
7
8#[derive(Clone)]
11pub(crate) struct Binding {
12 pub caster: Arc<AnyTypeCaster>,
13 pub builder: Arc<dyn Builder>,
14}
15
16impl Binding {
17 pub(crate) fn new(caster: Arc<AnyTypeCaster>, builder: Arc<dyn Builder>) -> Self {
18 Self { caster, builder }
19 }
20}
21
22pub struct TypecastBuilder<'a, Iface>
26where
27 Iface: 'static + ?Sized,
28{
29 builder: &'a dyn Builder,
30 caster: &'a TypeCaster<Iface>,
31}
32
33impl<Iface> Builder for TypecastBuilder<'_, Iface>
34where
35 Iface: 'static + ?Sized,
36{
37 fn instance_type(&self) -> TypeInfo {
38 self.builder.instance_type()
39 }
40
41 fn scope_type(&self) -> TypeInfo {
42 self.builder.scope_type()
43 }
44
45 fn interfaces(&self, clb: &mut dyn FnMut(&TypeInfo) -> bool) {
46 self.builder.interfaces(clb);
47 }
48
49 fn dependencies(&self, clb: &mut dyn FnMut(&DependencyInfo) -> bool) {
50 self.builder.dependencies(clb);
51 }
52
53 fn metadata<'b, 'c>(&'b self, clb: &'c mut dyn FnMut(&'b dyn Any) -> bool) {
54 self.builder.metadata(clb)
55 }
56
57 fn get_any(
58 &self,
59 cat: &Catalog,
60 ctx: &InjectionContext,
61 ) -> Result<Arc<dyn Any + Send + Sync>, InjectionError> {
62 self.builder.get_any(cat, ctx)
63 }
64}
65
66impl<'a, Iface> TypecastBuilder<'a, Iface>
67where
68 Iface: 'static + ?Sized,
69{
70 fn new(builder: &'a dyn Builder, caster: &'a TypeCaster<Iface>) -> Self {
71 Self { builder, caster }
72 }
73
74 pub fn get(&self, cat: &Catalog) -> Result<Arc<Iface>, InjectionError> {
75 self.get_with_context(cat, &InjectionContext::new_root())
76 }
77
78 pub fn get_with_context(
79 &self,
80 cat: &Catalog,
81 ctx: &InjectionContext,
82 ) -> Result<Arc<Iface>, InjectionError> {
83 let inst = self.builder.get_any(cat, ctx)?;
84 Ok((self.caster.cast_arc)(inst))
85 }
86}
87
88pub(crate) struct TypeCaster<Into: ?Sized> {
91 pub cast_arc: fn(Arc<dyn Any + Send + Sync>) -> Arc<Into>,
92}
93
94pub(crate) type AnyTypeCaster = dyn Any + Send + Sync;
95
96pub(crate) struct TypecastBuilderIterator<'a, Iface: 'static + ?Sized> {
99 bindings: Option<&'a Vec<Binding>>,
100 pos: usize,
101 _dummy: PhantomData<Iface>,
102}
103
104impl<'a, Iface: 'static + ?Sized> TypecastBuilderIterator<'a, Iface> {
105 pub(crate) fn new(bindings: Option<&'a Vec<Binding>>) -> Self {
106 Self {
107 bindings,
108 pos: 0,
109 _dummy: PhantomData,
110 }
111 }
112}
113
114impl<'a, Iface: 'static + ?Sized> Iterator for TypecastBuilderIterator<'a, Iface> {
115 type Item = TypecastBuilder<'a, Iface>;
116 fn next(&mut self) -> Option<Self::Item> {
117 if let Some(bindings) = self.bindings
118 && self.pos < bindings.len()
119 {
120 let b = &bindings[self.pos];
121 self.pos += 1;
122
123 let caster: &TypeCaster<Iface> = b.caster.downcast_ref().unwrap();
126 return Some(TypecastBuilder::new(b.builder.as_ref(), caster));
127 }
128 None
129 }
130}
131
132pub(crate) struct TypecastPredicateBuilderIterator<'a, Iface: 'static + ?Sized, Pred>
135where
136 Pred: Fn(&dyn Builder) -> bool,
137{
138 bindings: Option<&'a Vec<Binding>>,
139 pred: Pred,
140 pos: usize,
141 _dummy: PhantomData<Iface>,
142}
143
144impl<'a, Iface: 'static + ?Sized, Pred> TypecastPredicateBuilderIterator<'a, Iface, Pred>
145where
146 Pred: Fn(&dyn Builder) -> bool,
147{
148 pub(crate) fn new(bindings: Option<&'a Vec<Binding>>, pred: Pred) -> Self {
149 Self {
150 bindings,
151 pred,
152 pos: 0,
153 _dummy: PhantomData,
154 }
155 }
156}
157
158impl<'a, Iface: 'static + ?Sized, Pred> Iterator
159 for TypecastPredicateBuilderIterator<'a, Iface, Pred>
160where
161 Pred: Fn(&dyn Builder) -> bool,
162{
163 type Item = TypecastBuilder<'a, Iface>;
164 fn next(&mut self) -> Option<Self::Item> {
165 if let Some(bindings) = self.bindings {
166 while self.pos < bindings.len() {
167 let b = &bindings[self.pos];
168 self.pos += 1;
169
170 if (self.pred)(b.builder.as_ref()) {
171 let caster: &TypeCaster<Iface> = b.caster.downcast_ref().unwrap();
174 return Some(TypecastBuilder::new(b.builder.as_ref(), caster));
175 }
176 }
177 }
178 None
179 }
180}