spin_factors/runtime_factors.rs
1use wasmtime::component::{Linker, ResourceTable};
2
3use crate::{factor::FactorInstanceState, App, ConfiguredApp, Factor};
4
5/// A collection of `Factor`s that are initialized and configured together.
6///
7/// Implemented by `#[derive(RuntimeFactors)]` and should not be implemented manually.
8///
9/// # Example
10///
11/// A typical usage of `RuntimeFactors` would look something like the following pseudo-code:
12///
13/// ```ignore
14/// #[derive(RuntimeFactors)]
15/// struct MyFactors {
16/// // ...
17/// }
18/// // Initialize the factors collection
19/// let factors = MyFactors { /* .. */ };
20/// // Initialize each factor with a linker
21/// factors.init(&mut linker)?;
22/// // Configure the factors with an app and runtime config
23/// let configured_app = factors.configure_app(app, runtime_config)?;
24/// // Prepare instance state builders
25/// let builders = factors.prepare(&configured_app, "component-id")?;
26/// // Build the instance state for the factors
27/// let data = factors.build_instance_state(builders)?;
28/// // Initialize a `wasmtime` store with the instance state
29/// let mut store = wasmtime::Store::new(&engine, data);
30/// // Instantiate the component
31/// let instance = linker.instantiate_async(&mut store, &component).await?;
32/// ```
33pub trait RuntimeFactors: Send + Sync + Sized + 'static {
34 /// The per application state of all the factors.
35 type AppState: Sync + Send;
36 /// The per instance state of the factors.
37 type InstanceState: RuntimeFactorsInstanceState;
38 /// The collection of all the `InstanceBuilder`s of the factors.
39 type InstanceBuilders: Send + HasInstanceBuilder;
40 /// The runtime configuration of all the factors.
41 type RuntimeConfig: Default;
42
43 /// Initialize the factors with the given linker.
44 ///
45 /// Each factor's `init` is called in turn. Must be called once before
46 /// [`RuntimeFactors::prepare`].
47 fn init<T: AsInstanceState<Self::InstanceState> + Send + 'static>(
48 &mut self,
49 linker: &mut Linker<T>,
50 ) -> crate::Result<()>;
51
52 /// Configure the factors with the given app and runtime config.
53 fn configure_app(
54 &self,
55 app: App,
56 runtime_config: Self::RuntimeConfig,
57 ) -> crate::Result<ConfiguredApp<Self>>;
58
59 /// Prepare the factors' instance state builders.
60 fn prepare(
61 &self,
62 configured_app: &ConfiguredApp<Self>,
63 component_id: &str,
64 ) -> crate::Result<Self::InstanceBuilders>;
65
66 /// Build the instance state for the factors.
67 fn build_instance_state(
68 &self,
69 builders: Self::InstanceBuilders,
70 ) -> crate::Result<Self::InstanceState>;
71
72 /// Get the app state related to a particular factor.
73 fn app_state<F: Factor>(app_state: &Self::AppState) -> Option<&F::AppState>;
74
75 /// Get the instance builder of a particular factor.
76 ///
77 /// The outer `Option` is `None` if the factor has not been registered with this `Factors` collection,
78 /// and the inner `Option` is `None` if the factor has not been prepared yet.
79 fn instance_builder_mut<F: Factor>(
80 builders: &mut Self::InstanceBuilders,
81 ) -> Option<Option<&mut F::InstanceBuilder>>;
82}
83
84/// Allows querying an `InstanceBuilders` for a particular `Factor`'s `InstanceBuilder`.
85pub trait HasInstanceBuilder {
86 /// Get the instance builder of a particular factor.
87 fn for_factor<F: Factor>(&mut self) -> Option<&mut F::InstanceBuilder>;
88}
89
90/// Get the state of a particular Factor from the overall InstanceState
91///
92/// Implemented by `#[derive(RuntimeFactors)]`
93pub trait RuntimeFactorsInstanceState: AsInstanceState<Self> + Send + 'static {
94 fn get_with_table<F: Factor>(
95 &mut self,
96 ) -> Option<(&mut FactorInstanceState<F>, &mut ResourceTable)>;
97
98 fn get<F: Factor>(&mut self) -> Option<&mut FactorInstanceState<F>> {
99 self.get_with_table::<F>().map(|(state, _)| state)
100 }
101
102 fn table(&self) -> &ResourceTable;
103
104 fn table_mut(&mut self) -> &mut ResourceTable;
105}
106
107pub trait AsInstanceState<T: RuntimeFactorsInstanceState + ?Sized> {
108 fn as_instance_state(&mut self) -> &mut T;
109}