1- use  std :: sync :: Arc ; 
1+ mod  provider_type ; 
22
3+ use  std:: { collections:: HashMap ,  sync:: Arc } ; 
4+ 
5+ use  provider_type:: { provider_maker,  ProviderMaker } ; 
6+ use  serde:: Deserialize ; 
37use  spin_expressions:: ProviderResolver ; 
48use  spin_factors:: { 
5-     anyhow,  ConfigureAppContext ,  Factor ,  FactorInstanceBuilder ,  InitContext ,  InstanceBuilders , 
6-     PrepareContext ,  RuntimeFactors , 
9+     anyhow:: { self ,  bail,  Context } , 
10+     ConfigureAppContext ,  Factor ,  FactorRuntimeConfig ,  InitContext ,  InstanceBuilders , 
11+     PrepareContext ,  RuntimeFactors ,  SelfInstanceBuilder , 
712} ; 
813use  spin_world:: { async_trait,  v1:: config as  v1_config,  v2:: variables} ; 
914
10- pub  struct  VariablesFactor ; 
15+ pub  use  provider_type:: { StaticVariables ,  VariablesProviderType } ; 
16+ 
17+ #[ derive( Default ) ]  
18+ pub  struct  VariablesFactor  { 
19+     provider_types :  HashMap < & ' static  str ,  ProviderMaker > , 
20+ } 
21+ 
22+ impl  VariablesFactor  { 
23+     pub  fn  add_provider_type < T :  VariablesProviderType > ( 
24+         & mut  self , 
25+         provider_type :  T , 
26+     )  -> anyhow:: Result < ( ) >  { 
27+         if  self 
28+             . provider_types 
29+             . insert ( T :: TYPE ,  provider_maker ( provider_type) ) 
30+             . is_some ( ) 
31+         { 
32+             bail ! ( "duplicate provider type {:?}" ,  T :: TYPE ) ; 
33+         } 
34+         Ok ( ( ) ) 
35+     } 
36+ } 
1137
1238impl  Factor  for  VariablesFactor  { 
13-     type  RuntimeConfig  = ( ) ; 
39+     type  RuntimeConfig  = RuntimeConfig ; 
1440    type  AppState  = AppState ; 
15-     type  InstanceBuilder  = InstanceBuilder ; 
41+     type  InstanceBuilder  = InstanceState ; 
1642
1743    fn  init < Factors :  RuntimeFactors > ( 
1844        & mut  self , 
@@ -25,18 +51,30 @@ impl Factor for VariablesFactor {
2551
2652    fn  configure_app < T :  RuntimeFactors > ( 
2753        & self , 
28-         ctx :  ConfigureAppContext < T ,  Self > , 
54+         mut   ctx :  ConfigureAppContext < T ,  Self > , 
2955    )  -> anyhow:: Result < Self :: AppState >  { 
3056        let  app = ctx. app ( ) ; 
3157        let  mut  resolver =
3258            ProviderResolver :: new ( app. variables ( ) . map ( |( key,  val) | ( key. clone ( ) ,  val. clone ( ) ) ) ) ?; 
59+ 
3360        for  component in  app. components ( )  { 
3461            resolver. add_component_variables ( 
3562                component. id ( ) , 
3663                component. config ( ) . map ( |( k,  v) | ( k. into ( ) ,  v. into ( ) ) ) , 
3764            ) ?; 
3865        } 
39-         // TODO: add providers from runtime config 
66+ 
67+         if  let  Some ( runtime_config)  = ctx. take_runtime_config ( )  { 
68+             for  ProviderConfig  {  type_,  config }  in  runtime_config. provider_configs  { 
69+                 let  provider_maker = self 
70+                     . provider_types 
71+                     . get ( type_. as_str ( ) ) 
72+                     . with_context ( || format ! ( "unknown variables provider type {type_}" ) ) ?; 
73+                 let  provider = provider_maker ( config) ?; 
74+                 resolver. add_provider ( provider) ; 
75+             } 
76+         } 
77+ 
4078        Ok ( AppState  { 
4179            resolver :  Arc :: new ( resolver) , 
4280        } ) 
@@ -45,47 +83,51 @@ impl Factor for VariablesFactor {
4583    fn  prepare < T :  RuntimeFactors > ( 
4684        ctx :  PrepareContext < Self > , 
4785        _builders :  & mut  InstanceBuilders < T > , 
48-     )  -> anyhow:: Result < InstanceBuilder >  { 
86+     )  -> anyhow:: Result < InstanceState >  { 
4987        let  component_id = ctx. app_component ( ) . id ( ) . to_string ( ) ; 
5088        let  resolver = ctx. app_state ( ) . resolver . clone ( ) ; 
51-         Ok ( InstanceBuilder  { 
52-             state :  InstanceState  { 
53-                 component_id, 
54-                 resolver, 
55-             } , 
89+         Ok ( InstanceState  { 
90+             component_id, 
91+             resolver, 
5692        } ) 
5793    } 
5894} 
5995
60- #[ derive( Default ) ]  
61- pub  struct  AppState  { 
62-     resolver :  Arc < ProviderResolver > , 
96+ #[ derive( Deserialize ) ]  
97+ #[ serde( transparent) ]  
98+ pub  struct  RuntimeConfig  { 
99+     provider_configs :  Vec < ProviderConfig > , 
63100} 
64101
65- pub   struct   InstanceBuilder  { 
66-     state :   InstanceState , 
102+ impl   FactorRuntimeConfig   for   RuntimeConfig  { 
103+     const   KEY :   & ' static   str  =  "variable_provider" ; 
67104} 
68105
69- impl  InstanceBuilder  { 
70-     pub  fn  resolver ( & self )  -> & Arc < ProviderResolver >  { 
71-         & self . state . resolver 
72-     } 
106+ #[ derive( Deserialize ) ]  
107+ struct  ProviderConfig  { 
108+     #[ serde( rename = "type" ) ]  
109+     type_ :  String , 
110+     #[ serde( flatten) ]  
111+     config :  toml:: Table , 
73112} 
74113
75- impl  FactorInstanceBuilder  for  InstanceBuilder  { 
76-     type  InstanceState  = InstanceState ; 
77- 
78-     fn  build ( self )  -> anyhow:: Result < Self :: InstanceState >  { 
79-         Ok ( self . state ) 
80-     } 
114+ pub  struct  AppState  { 
115+     resolver :  Arc < ProviderResolver > , 
81116} 
82117
83- #[ derive( Default ) ]  
84118pub  struct  InstanceState  { 
85119    component_id :  String , 
86120    resolver :  Arc < ProviderResolver > , 
87121} 
88122
123+ impl  InstanceState  { 
124+     pub  fn  resolver ( & self )  -> & Arc < ProviderResolver >  { 
125+         & self . resolver 
126+     } 
127+ } 
128+ 
129+ impl  SelfInstanceBuilder  for  InstanceState  { } 
130+ 
89131#[ async_trait]  
90132impl  variables:: Host  for  InstanceState  { 
91133    async  fn  get ( & mut  self ,  key :  String )  -> Result < String ,  variables:: Error >  { 
0 commit comments