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