1+ use std:: collections:: HashMap ;
2+
3+ use magnus:: { Error , RHash , Ruby , function, prelude:: * , scan_args, class} ;
4+ use temporal_sdk_core_api:: envconfig:: {
5+ load_client_config as core_load_client_config,
6+ load_client_config_profile as core_load_client_config_profile,
7+ ClientConfig as CoreClientConfig , ClientConfigCodec , ClientConfigProfile as CoreClientConfigProfile ,
8+ ClientConfigTLS as CoreClientConfigTLS , DataSource , LoadClientConfigOptions ,
9+ LoadClientConfigProfileOptions ,
10+ } ;
11+
12+ use crate :: { ROOT_MOD , error} ;
13+
14+ pub fn init ( ruby : & Ruby ) -> Result < ( ) , Error > {
15+ let root_mod = ruby. get_inner ( & ROOT_MOD ) ;
16+
17+ let class = root_mod. define_class ( "EnvConfig" , class:: object ( ) ) ?;
18+ class. define_singleton_method ( "load_client_config" , function ! ( load_client_config, -1 ) ) ?;
19+ class. define_singleton_method ( "load_client_connect_config" , function ! ( load_client_connect_config, -1 ) ) ?;
20+
21+ Ok ( ( ) )
22+ }
23+
24+ fn data_source_to_hash ( ruby : & Ruby , ds : & DataSource ) -> Result < RHash , Error > {
25+ let hash = RHash :: new ( ) ;
26+ match ds {
27+ DataSource :: Path ( p) => {
28+ hash. aset ( "path" , ruby. str_new ( p) ) ?;
29+ }
30+ DataSource :: Data ( d) => {
31+ hash. aset ( "data" , ruby. str_from_slice ( d) ) ?;
32+ }
33+ }
34+ Ok ( hash)
35+ }
36+
37+ fn tls_to_hash ( ruby : & Ruby , tls : & CoreClientConfigTLS ) -> Result < RHash , Error > {
38+ let hash = RHash :: new ( ) ;
39+ hash. aset ( "disabled" , tls. disabled ) ?;
40+
41+ if let Some ( v) = & tls. client_cert {
42+ hash. aset ( "client_cert" , data_source_to_hash ( ruby, v) ?) ?;
43+ }
44+ if let Some ( v) = & tls. client_key {
45+ hash. aset ( "client_key" , data_source_to_hash ( ruby, v) ?) ?;
46+ }
47+ if let Some ( v) = & tls. server_ca_cert {
48+ hash. aset ( "server_ca_cert" , data_source_to_hash ( ruby, v) ?) ?;
49+ }
50+ if let Some ( v) = & tls. server_name {
51+ hash. aset ( "server_name" , ruby. str_new ( v) ) ?;
52+ }
53+ hash. aset ( "disable_host_verification" , tls. disable_host_verification ) ?;
54+
55+ Ok ( hash)
56+ }
57+
58+ fn codec_to_hash ( ruby : & Ruby , codec : & ClientConfigCodec ) -> Result < RHash , Error > {
59+ let hash = RHash :: new ( ) ;
60+ if let Some ( v) = & codec. endpoint {
61+ hash. aset ( "endpoint" , ruby. str_new ( v) ) ?;
62+ }
63+ if let Some ( v) = & codec. auth {
64+ hash. aset ( "auth" , ruby. str_new ( v) ) ?;
65+ }
66+ Ok ( hash)
67+ }
68+
69+ fn profile_to_hash ( ruby : & Ruby , profile : & CoreClientConfigProfile ) -> Result < RHash , Error > {
70+ let hash = RHash :: new ( ) ;
71+
72+ if let Some ( v) = & profile. address {
73+ hash. aset ( "address" , ruby. str_new ( v) ) ?;
74+ }
75+ if let Some ( v) = & profile. namespace {
76+ hash. aset ( "namespace" , ruby. str_new ( v) ) ?;
77+ }
78+ if let Some ( v) = & profile. api_key {
79+ hash. aset ( "api_key" , ruby. str_new ( v) ) ?;
80+ }
81+ if let Some ( tls) = & profile. tls {
82+ hash. aset ( "tls" , tls_to_hash ( ruby, tls) ?) ?;
83+ }
84+ if let Some ( codec) = & profile. codec {
85+ hash. aset ( "codec" , codec_to_hash ( ruby, codec) ?) ?;
86+ }
87+ if !profile. grpc_meta . is_empty ( ) {
88+ let grpc_meta_hash = RHash :: new ( ) ;
89+ for ( k, v) in & profile. grpc_meta {
90+ grpc_meta_hash. aset ( ruby. str_new ( k) , ruby. str_new ( v) ) ?;
91+ }
92+ hash. aset ( "grpc_meta" , grpc_meta_hash) ?;
93+ }
94+
95+ Ok ( hash)
96+ }
97+
98+ fn core_config_to_hash ( ruby : & Ruby , core_config : & CoreClientConfig ) -> Result < RHash , Error > {
99+ let profiles_hash = RHash :: new ( ) ;
100+ for ( name, profile) in & core_config. profiles {
101+ let profile_hash = profile_to_hash ( ruby, profile) ?;
102+ profiles_hash. aset ( ruby. str_new ( name) , profile_hash) ?;
103+ }
104+ Ok ( profiles_hash)
105+ }
106+
107+ fn load_client_config_inner (
108+ ruby : & Ruby ,
109+ config_source : Option < DataSource > ,
110+ config_file_strict : bool ,
111+ disable_file : bool ,
112+ env_vars : Option < HashMap < String , String > > ,
113+ ) -> Result < RHash , Error > {
114+ let core_config = if disable_file {
115+ CoreClientConfig :: default ( )
116+ } else {
117+ let options = LoadClientConfigOptions {
118+ config_source,
119+ config_file_strict,
120+ } ;
121+ core_load_client_config ( options, env_vars. as_ref ( ) )
122+ . map_err ( |e| error ! ( "EnvConfig error: {}" , e) ) ?
123+ } ;
124+
125+ core_config_to_hash ( ruby, & core_config)
126+ }
127+
128+ fn load_client_connect_config_inner (
129+ ruby : & Ruby ,
130+ config_source : Option < DataSource > ,
131+ profile : Option < String > ,
132+ disable_file : bool ,
133+ disable_env : bool ,
134+ config_file_strict : bool ,
135+ env_vars : Option < HashMap < String , String > > ,
136+ ) -> Result < RHash , Error > {
137+ let options = LoadClientConfigProfileOptions {
138+ config_source,
139+ config_file_profile : profile,
140+ config_file_strict,
141+ disable_file,
142+ disable_env,
143+ } ;
144+
145+ let profile = core_load_client_config_profile ( options, env_vars. as_ref ( ) )
146+ . map_err ( |e| error ! ( "EnvConfig error: {}" , e) ) ?;
147+
148+ profile_to_hash ( ruby, & profile)
149+ }
150+
151+ // load_client_config(path: String|nil, data: String|nil, disable_file: bool, config_file_strict: bool, env_vars: Hash|nil)
152+ fn load_client_config ( args : & [ magnus:: Value ] ) -> Result < RHash , Error > {
153+ let ruby = Ruby :: get ( ) . expect ( "Not in Ruby thread" ) ;
154+ let args = scan_args:: scan_args :: <
155+ ( Option < String > , Option < Vec < u8 > > , bool , bool ) ,
156+ ( Option < HashMap < String , String > > , ) ,
157+ ( ) ,
158+ ( ) ,
159+ ( ) ,
160+ ( ) ,
161+ > ( args) ?;
162+ let ( path, data, disable_file, config_file_strict) = args. required ;
163+ let ( env_vars, ) = args. optional ;
164+
165+ let config_source = match ( path, data) {
166+ ( Some ( p) , None ) => Some ( DataSource :: Path ( p) ) ,
167+ ( None , Some ( d) ) => Some ( DataSource :: Data ( d) ) ,
168+ ( None , None ) => None ,
169+ ( Some ( _) , Some ( _) ) => {
170+ return Err ( error ! ( "Cannot specify both path and data for config source" ) ) ;
171+ }
172+ } ;
173+
174+ load_client_config_inner (
175+ & ruby,
176+ config_source,
177+ config_file_strict,
178+ disable_file,
179+ env_vars,
180+ )
181+ }
182+
183+ // load_client_connect_config(profile: String|nil, path: String|nil, data: String|nil, disable_file: bool, disable_env: bool, config_file_strict: bool, env_vars: Hash|nil)
184+ fn load_client_connect_config ( args : & [ magnus:: Value ] ) -> Result < RHash , Error > {
185+ let ruby = Ruby :: get ( ) . expect ( "Not in Ruby thread" ) ;
186+ let args = scan_args:: scan_args :: <
187+ ( Option < String > , Option < String > , Option < Vec < u8 > > , bool , bool , bool ) ,
188+ ( Option < HashMap < String , String > > , ) ,
189+ ( ) ,
190+ ( ) ,
191+ ( ) ,
192+ ( ) ,
193+ > ( args) ?;
194+ let ( profile, path, data, disable_file, disable_env, config_file_strict) = args. required ;
195+ let ( env_vars, ) = args. optional ;
196+
197+ let config_source = match ( path, data) {
198+ ( Some ( p) , None ) => Some ( DataSource :: Path ( p) ) ,
199+ ( None , Some ( d) ) => Some ( DataSource :: Data ( d) ) ,
200+ ( None , None ) => None ,
201+ ( Some ( _) , Some ( _) ) => {
202+ return Err ( error ! ( "Cannot specify both path and data for config source" ) ) ;
203+ }
204+ } ;
205+
206+ load_client_connect_config_inner (
207+ & ruby,
208+ config_source,
209+ profile,
210+ disable_file,
211+ disable_env,
212+ config_file_strict,
213+ env_vars,
214+ )
215+ }
0 commit comments