1use std::any::Any;
2
3use spin_app::AppComponent;
4
5use crate::{Error, Factor, RuntimeFactors};
6
7pub trait FactorInstanceBuilder: Any {
9 type InstanceState: Send + 'static;
15
16 fn build(self) -> anyhow::Result<Self::InstanceState>;
18}
19
20impl FactorInstanceBuilder for () {
21 type InstanceState = ();
22
23 fn build(self) -> anyhow::Result<Self::InstanceState> {
24 Ok(())
25 }
26}
27
28pub trait SelfInstanceBuilder: Send + 'static {}
30
31impl<T: SelfInstanceBuilder> FactorInstanceBuilder for T {
32 type InstanceState = Self;
33
34 fn build(self) -> anyhow::Result<Self::InstanceState> {
35 Ok(self)
36 }
37}
38
39pub struct PrepareContext<'a, T: RuntimeFactors, F: Factor> {
43 pub(crate) app_state: &'a F::AppState,
44 pub(crate) app_component: &'a AppComponent<'a>,
45 pub(crate) instance_builders: &'a mut T::InstanceBuilders,
46}
47
48impl<'a, T: RuntimeFactors, F: Factor> PrepareContext<'a, T, F> {
49 #[doc(hidden)]
50 pub fn new(
51 app_state: &'a F::AppState,
52 app_component: &'a AppComponent,
53 instance_builders: &'a mut T::InstanceBuilders,
54 ) -> Self {
55 Self {
56 app_state,
57 app_component,
58 instance_builders,
59 }
60 }
61
62 pub fn app_state(&self) -> &'a F::AppState {
64 self.app_state
65 }
66
67 pub fn app_component(&self) -> &'a AppComponent {
69 self.app_component
70 }
71
72 pub fn instance_builder<U: Factor>(&mut self) -> crate::Result<&mut U::InstanceBuilder> {
78 T::instance_builder_mut::<U>(self.instance_builders)
79 .ok_or(Error::no_such_factor::<U>())?
80 .ok_or_else(|| {
81 Error::DependencyOrderingError(format!(
82 "{factor} builder requested before it was prepared",
83 factor = std::any::type_name::<U>()
84 ))
85 })
86 }
87}