@@ -8,13 +8,50 @@ use temporal_sdk_core_api::envconfig::{
88 DataSource as CoreDataSource , LoadClientConfigOptions , LoadClientConfigProfileOptions ,
99} ;
1010
11- /// Callback for client config load operations.
12- /// If success or fail are not null, they must be manually freed when done.
13- pub type ClientConfigCallback = unsafe extern "C" fn (
14- user_data : * mut libc:: c_void ,
15- success : * const ByteArray ,
16- fail : * const ByteArray ,
17- ) ;
11+ /// OrFail result for client config loading operations.
12+ /// Either success or fail will be null, but never both.
13+ /// If success is not null, it contains JSON-serialized client configuration data.
14+ /// If fail is not null, it contains UTF-8 encoded error message.
15+ /// The returned ByteArrays must be freed by the caller.
16+ #[ repr( C ) ]
17+ pub struct ClientConfigOrFail {
18+ pub success : * const ByteArray ,
19+ pub fail : * const ByteArray ,
20+ }
21+
22+ /// OrFail result for client config profile loading operations.
23+ /// Either success or fail will be null, but never both.
24+ /// If success is not null, it contains JSON-serialized client configuration profile data.
25+ /// If fail is not null, it contains UTF-8 encoded error message.
26+ /// The returned ByteArrays must be freed by the caller.
27+ #[ repr( C ) ]
28+ pub struct ClientConfigProfileOrFail {
29+ pub success : * const ByteArray ,
30+ pub fail : * const ByteArray ,
31+ }
32+
33+
34+ /// Options for loading client configuration.
35+ #[ repr( C ) ]
36+ pub struct ClientConfigLoadOptions {
37+ pub path : * const libc:: c_char ,
38+ pub data : ByteArrayRef ,
39+ pub disable_file : bool ,
40+ pub config_file_strict : bool ,
41+ pub env_vars : ByteArrayRef ,
42+ }
43+
44+ /// Options for loading a specific client configuration profile.
45+ #[ repr( C ) ]
46+ pub struct ClientConfigProfileLoadOptions {
47+ pub profile : * const libc:: c_char ,
48+ pub path : * const libc:: c_char ,
49+ pub data : ByteArrayRef ,
50+ pub disable_file : bool ,
51+ pub disable_env : bool ,
52+ pub config_file_strict : bool ,
53+ pub env_vars : ByteArrayRef ,
54+ }
1855
1956// Wrapper types for JSON serialization
2057#[ derive( Serialize ) ]
@@ -155,97 +192,134 @@ fn parse_env_vars(env_vars: ByteArrayRef) -> Result<Option<HashMap<String, Strin
155192 . map_err ( |e| format ! ( "Invalid env vars JSON: {e}" ) )
156193}
157194
158- fn send_result < T : Serialize > (
159- result : Result < T , String > ,
160- user_data : * mut libc:: c_void ,
161- callback : ClientConfigCallback ,
162- ) {
163- match result {
164- Ok ( data) => match serde_json:: to_vec ( & data) {
165- Ok ( json_bytes) => {
166- let result = ByteArray :: from_vec ( json_bytes) ;
167- unsafe { callback ( user_data, result. into_raw ( ) , std:: ptr:: null ( ) ) } ;
168- }
169- Err ( e) => {
170- let err = ByteArray :: from_utf8 ( format ! ( "Failed to serialize: {e}" ) ) ;
171- unsafe { callback ( user_data, std:: ptr:: null ( ) , err. into_raw ( ) ) } ;
172- }
173- } ,
195+ // Simple helper to handle serialization errors consistently
196+ fn serialize_or_error < T : Serialize > ( data : T ) -> Result < * const ByteArray , * const ByteArray > {
197+ match serde_json:: to_vec ( & data) {
198+ Ok ( json_bytes) => {
199+ let result = ByteArray :: from_vec ( json_bytes) ;
200+ Ok ( result. into_raw ( ) )
201+ }
174202 Err ( e) => {
175- let err = ByteArray :: from_utf8 ( e ) ;
176- unsafe { callback ( user_data , std :: ptr :: null ( ) , err. into_raw ( ) ) } ;
203+ let err = ByteArray :: from_utf8 ( format ! ( "Failed to serialize: {e}" ) ) ;
204+ Err ( err. into_raw ( ) )
177205 }
178206 }
179207}
180208
181- /// Load all client profiles from given sources
209+
210+ /// Load all client profiles from given sources.
211+ /// Returns ClientConfigOrFail with either success JSON or error message.
212+ /// The returned ByteArrays must be freed by the caller.
182213#[ unsafe( no_mangle) ]
183214pub extern "C" fn temporal_core_client_config_load (
184- path : * const libc:: c_char ,
185- data : ByteArrayRef ,
186- disable_file : bool ,
187- config_file_strict : bool ,
188- env_vars : ByteArrayRef ,
189- user_data : * mut libc:: c_void ,
190- callback : ClientConfigCallback ,
191- ) {
215+ options : * const ClientConfigLoadOptions ,
216+ ) -> ClientConfigOrFail {
217+ if options. is_null ( ) {
218+ let err = ByteArray :: from_utf8 ( "Options cannot be null" . to_string ( ) ) ;
219+ return ClientConfigOrFail {
220+ success : std:: ptr:: null ( ) ,
221+ fail : err. into_raw ( ) ,
222+ } ;
223+ }
224+
192225 let result = || -> Result < ClientConfig , String > {
193- let config_source = parse_config_source ( path, data) ?;
194- let env_vars_map = parse_env_vars ( env_vars) ?;
226+ let opts = unsafe { & * options } ;
227+ let config_source = parse_config_source ( opts. path , opts. data ) ?;
228+ let env_vars_map = parse_env_vars ( opts. env_vars ) ?;
195229
196- let options = LoadClientConfigOptions {
197- config_source : if disable_file { None } else { config_source } ,
198- config_file_strict,
230+ let load_options = LoadClientConfigOptions {
231+ config_source : if opts . disable_file { None } else { config_source } ,
232+ config_file_strict : opts . config_file_strict ,
199233 } ;
200234
201- let core_config = envconfig:: load_client_config ( options , env_vars_map. as_ref ( ) )
235+ let core_config = envconfig:: load_client_config ( load_options , env_vars_map. as_ref ( ) )
202236 . map_err ( |e| e. to_string ( ) ) ?;
203237
204238 Ok ( core_config. into ( ) )
205239 } ;
206240
207- send_result ( result ( ) , user_data, callback) ;
241+ match result ( ) {
242+ Ok ( data) => match serialize_or_error ( data) {
243+ Ok ( success) => ClientConfigOrFail {
244+ success,
245+ fail : std:: ptr:: null ( ) ,
246+ } ,
247+ Err ( fail) => ClientConfigOrFail {
248+ success : std:: ptr:: null ( ) ,
249+ fail,
250+ } ,
251+ } ,
252+ Err ( e) => {
253+ let err = ByteArray :: from_utf8 ( e) ;
254+ ClientConfigOrFail {
255+ success : std:: ptr:: null ( ) ,
256+ fail : err. into_raw ( ) ,
257+ }
258+ }
259+ }
208260}
209261
210- /// Load a single client profile from given sources with env overrides
262+ /// Load a single client profile from given sources with env overrides.
263+ /// Returns ClientConfigProfileOrFail with either success JSON or error message.
264+ /// The returned ByteArrays must be freed by the caller.
211265#[ unsafe( no_mangle) ]
212266pub extern "C" fn temporal_core_client_config_profile_load (
213- profile : * const libc :: c_char ,
214- path : * const libc :: c_char ,
215- data : ByteArrayRef ,
216- disable_file : bool ,
217- disable_env : bool ,
218- config_file_strict : bool ,
219- env_vars : ByteArrayRef ,
220- user_data : * mut libc :: c_void ,
221- callback : ClientConfigCallback ,
222- ) {
267+ options : * const ClientConfigProfileLoadOptions ,
268+ ) -> ClientConfigProfileOrFail {
269+ if options . is_null ( ) {
270+ let err = ByteArray :: from_utf8 ( "Options cannot be null" . to_string ( ) ) ;
271+ return ClientConfigProfileOrFail {
272+ success : std :: ptr :: null ( ) ,
273+ fail : err . into_raw ( ) ,
274+ } ;
275+ }
276+
223277 let result = || -> Result < ClientConfigProfile , String > {
224- let profile_name = if !profile. is_null ( ) {
225- match unsafe { CStr :: from_ptr ( profile) } . to_str ( ) {
278+ let opts = unsafe { & * options } ;
279+
280+ let profile_name = if !opts. profile . is_null ( ) {
281+ match unsafe { CStr :: from_ptr ( opts. profile ) } . to_str ( ) {
226282 Ok ( s) => Some ( s. to_string ( ) ) ,
227283 Err ( e) => return Err ( format ! ( "Invalid profile UTF-8: {e}" ) ) ,
228284 }
229285 } else {
230286 None
231287 } ;
232288
233- let config_source = parse_config_source ( path, data) ?;
234- let env_vars_map = parse_env_vars ( env_vars) ?;
289+ let config_source = parse_config_source ( opts . path , opts . data ) ?;
290+ let env_vars_map = parse_env_vars ( opts . env_vars ) ?;
235291
236- let options = LoadClientConfigProfileOptions {
292+ let load_options = LoadClientConfigProfileOptions {
237293 config_source,
238294 config_file_profile : profile_name,
239- config_file_strict,
240- disable_file,
241- disable_env,
295+ config_file_strict : opts . config_file_strict ,
296+ disable_file : opts . disable_file ,
297+ disable_env : opts . disable_env ,
242298 } ;
243299
244- let profile = envconfig:: load_client_config_profile ( options , env_vars_map. as_ref ( ) )
300+ let profile = envconfig:: load_client_config_profile ( load_options , env_vars_map. as_ref ( ) )
245301 . map_err ( |e| e. to_string ( ) ) ?;
246302
247303 Ok ( profile. into ( ) )
248304 } ;
249305
250- send_result ( result ( ) , user_data, callback) ;
306+ match result ( ) {
307+ Ok ( data) => match serialize_or_error ( data) {
308+ Ok ( success) => ClientConfigProfileOrFail {
309+ success,
310+ fail : std:: ptr:: null ( ) ,
311+ } ,
312+ Err ( fail) => ClientConfigProfileOrFail {
313+ success : std:: ptr:: null ( ) ,
314+ fail,
315+ } ,
316+ } ,
317+ Err ( e) => {
318+ let err = ByteArray :: from_utf8 ( e) ;
319+ ClientConfigProfileOrFail {
320+ success : std:: ptr:: null ( ) ,
321+ fail : err. into_raw ( ) ,
322+ }
323+ }
324+ }
251325}
0 commit comments