11use crate :: { bridge_api, c_char, c_int, c_void, CStr , PathBuf } ;
22
3+ use std:: fmt:: Display ;
4+
35use metacall_registrator;
46
5- fn rs_loader_impl_load_from_file_on_error ( error : & str ) -> * mut c_void {
7+ fn rs_loader_impl_load_from_file_on_error < T : Display > ( error : T ) -> * mut c_void {
68 eprintln ! ( "{}" , error) ;
79
810 0 as c_int as * mut c_void
@@ -15,43 +17,63 @@ pub extern "C" fn rs_loader_impl_load_from_file(
1517 size : usize ,
1618) -> * mut c_void {
1719 let loader_lifecycle_state = bridge_api:: get_loader_lifecycle_state ( loader_impl) ;
18- let mut execution_paths_iterator = unsafe { ( * loader_lifecycle_state) . execution_paths . iter ( ) } ;
1920
2021 for i in 0 ..size {
2122 let path: * const c_char = paths. wrapping_offset ( i as isize ) as * const c_char ;
2223 let path_slice = unsafe { CStr :: from_ptr ( path) } . to_str ( ) . unwrap ( ) ;
2324 let mut path_buf = PathBuf :: from ( path_slice) ;
2425
26+ let mut execution_paths_iterator =
27+ unsafe { ( * loader_lifecycle_state) . execution_paths . iter ( ) } ;
28+
2529 if !path_buf. is_absolute ( ) {
26- let execution_path = execution_paths_iterator. next ( ) ;
30+ loop {
31+ let execution_path_current_iteration = execution_paths_iterator. next ( ) ;
32+ let original_path_buf = path_buf. clone ( ) ;
33+
34+ match execution_path_current_iteration {
35+ Some ( original_execution_path) => {
36+ let mut execution_path = original_execution_path. clone ( ) ;
37+ let mut execution_path_as_str = execution_path. to_str ( ) . unwrap ( ) ;
38+
39+ if !execution_path_as_str. ends_with ( "/" ) {
40+ execution_path =
41+ PathBuf :: from ( format ! ( "{}{}" , execution_path_as_str, "/" ) ) ;
2742
28- match execution_path {
29- Some ( execution_path) => {
30- let mut execution_path = execution_path. clone ( ) ;
31- let mut execution_path_as_str = execution_path. to_str ( ) . unwrap ( ) ;
43+ //Reassign the execution_path_as_str since the execution_path got changed
44+ execution_path_as_str = execution_path. to_str ( ) . unwrap ( ) ;
45+ }
3246
33- if !execution_path_as_str. ends_with ( "/" ) {
34- execution_path = PathBuf :: from ( format ! ( "{}{}" , execution_path_as_str, "/" ) ) ;
47+ path_buf = PathBuf :: from ( format ! (
48+ "{}{}" ,
49+ execution_path_as_str,
50+ path_buf. to_str( ) . unwrap( )
51+ ) ) ;
3552
36- //Reassign the execution_path_as_str since the execution_path got changed
37- execution_path_as_str = execution_path. to_str ( ) . unwrap ( ) ;
53+ if !path_buf. exists ( ) || !path_buf. is_file ( ) {
54+ path_buf = PathBuf :: from ( original_path_buf) ;
55+
56+ continue ;
57+ }
58+ }
59+ None => {
60+ return rs_loader_impl_load_from_file_on_error ( format ! (
61+ "Rs_loader was unable to find any suitable execution_path for the path: {}" ,
62+ original_path_buf. to_str( ) . unwrap( )
63+ ) )
3864 }
65+ } ;
3966
40- path_buf = PathBuf :: from ( format ! (
41- "{}{}" ,
42- execution_path_as_str,
43- path_buf. to_str( ) . unwrap( )
44- ) ) ;
67+ if path_buf. exists ( ) && path_buf. is_file ( ) {
68+ break ;
4569 }
46- None => {
47- return rs_loader_impl_load_from_file_on_error (
48- "Execution path's length is less than non-absolute path's length" ,
49- )
50- }
51- } ;
70+ }
5271 }
5372 if !path_buf. is_file ( ) {
54- return rs_loader_impl_load_from_file_on_error ( "Not a valid path to a file" ) ;
73+ return rs_loader_impl_load_from_file_on_error ( format ! (
74+ "Not a valid absolute path to a file, {}" ,
75+ path_buf. to_str( ) . unwrap( )
76+ ) ) ;
5577 }
5678
5779 let cargo_cdylib_project =
0 commit comments