33// Licensed under MIT License, see License file for more details
44// git clone https://github.com/marcomq/tauri-plugin-python
55
6- use std:: env;
7- use std:: path:: PathBuf ;
86use std:: sync:: atomic:: AtomicBool ;
97use std:: { collections:: HashMap , ffi:: CString , sync:: Mutex } ;
108
@@ -14,7 +12,7 @@ use pyo3::types::{PyAnyMethods, PyDictMethods, PyList, PyListMethods};
1412use pyo3:: PyErr ;
1513use pyo3:: { marker, types:: PyDict , Py , PyAny , PyResult } ;
1614
17- use crate :: models:: * ;
15+ use crate :: { models:: * , Error } ;
1816
1917lazy_static ! {
2018 static ref INIT_BLOCKED : AtomicBool = false . into( ) ;
@@ -23,55 +21,56 @@ lazy_static! {
2321 Mutex :: new( marker:: Python :: with_gil( |py| { PyDict :: new( py) . into( ) } ) ) ;
2422}
2523
24+ fn get_py_path ( ) -> std:: path:: PathBuf {
25+ std:: env:: current_dir ( )
26+ . unwrap ( )
27+ . join ( "src-python" )
28+ }
29+
2630pub fn init_python ( code : String ) -> crate :: Result < ( ) > {
2731 let c_code = CString :: new ( code) . expect ( "error creating cstring from code" ) ;
28- marker:: Python :: with_gil ( |py| -> PyResult < ( ) > {
32+ Ok ( marker:: Python :: with_gil ( |py| -> PyResult < ( ) > {
2933 let syspath = py
3034 . import ( "sys" ) ?
3135 . getattr ( "path" ) ?
3236 . downcast_into :: < PyList > ( ) ?;
3337 syspath. insert ( 0 , get_py_path ( ) . to_str ( ) ) ?;
3438 let globals = GLOBALS . lock ( ) . unwrap ( ) . clone_ref ( py) . into_bound ( py) ;
3539 py. run ( & c_code, Some ( & globals) , None )
36- } )
40+ } ) ? )
3741}
3842
39- pub fn run_python ( payload : StringRequest ) -> PyResult < ( ) > {
40- marker:: Python :: with_gil ( |py| {
43+ pub fn run_python ( payload : StringRequest ) -> crate :: Result < ( ) > {
44+ marker:: Python :: with_gil ( |py| -> crate :: Result < ( ) > {
4145 let globals = GLOBALS . lock ( ) . unwrap ( ) . clone_ref ( py) . into_bound ( py) ;
42- let code_c = CString :: new ( payload. value ) . expect ( "CString::new failed" ) ;
43- py. run ( & code_c , Some ( & globals) , None )
46+ let c_code = CString :: new ( payload. value ) . expect ( "CString::new failed" ) ;
47+ Ok ( py. run ( & c_code , Some ( & globals) , None ) ? )
4448 } )
4549}
46- pub fn register_function ( payload : RegisterRequest ) -> PyResult < ( ) > {
50+ pub fn register_function ( payload : RegisterRequest ) -> crate :: Result < ( ) > {
4751 register_function_str ( payload. python_function_call , payload. number_of_args )
4852}
4953
50- pub fn register_function_str ( fn_name : String , number_of_args : Option < u8 > ) -> PyResult < ( ) > {
54+ pub fn register_function_str ( fn_name : String , number_of_args : Option < u8 > ) -> crate :: Result < ( ) > {
5155 // TODO, check actual function signature
5256 if INIT_BLOCKED . load ( std:: sync:: atomic:: Ordering :: Relaxed ) {
53- return Err ( pyo3:: exceptions:: PyException :: new_err (
54- "Cannot register after function called" ,
55- ) ) ;
57+ return Err ( "Cannot register after function called" . into ( ) ) ;
5658 }
57- marker:: Python :: with_gil ( |py| -> PyResult < ( ) > {
59+ marker:: Python :: with_gil ( |py| -> crate :: Result < ( ) > {
5860 let globals = GLOBALS . lock ( ) . unwrap ( ) . clone_ref ( py) . into_bound ( py) ;
5961
6062 let fn_dot_split: Vec < & str > = fn_name. split ( "." ) . collect ( ) ;
6163 let app = globals. get_item ( & fn_dot_split[ 0 ] ) ?;
6264 if app. is_none ( ) {
63- return Err ( pyo3:: exceptions:: PyException :: new_err ( format ! (
64- "{} not found" ,
65- & fn_name
66- ) ) ) ;
65+ return Err ( Error :: String ( format ! ( "{} not found" , & fn_name) ) ) ;
6766 }
6867 let app = if fn_dot_split. len ( ) > 1 {
6968 app. unwrap ( ) . getattr ( fn_dot_split. get ( 1 ) . unwrap ( ) ) ?
7069 } else {
7170 app. unwrap ( )
7271 } ;
7372 if !app. is_callable ( ) {
74- return Err ( pyo3 :: exceptions :: PyException :: new_err ( format ! (
73+ return Err ( Error :: String ( format ! (
7574 "{} not a callable function" ,
7675 & fn_name
7776 ) ) ) ;
@@ -95,30 +94,30 @@ if True:
9594 Ok ( ( ) )
9695 } )
9796}
98- pub fn call_function ( payload : RunRequest ) -> PyResult < Py < PyAny > > {
97+ pub fn call_function ( payload : RunRequest ) -> crate :: Result < String > {
9998 INIT_BLOCKED . store ( true , std:: sync:: atomic:: Ordering :: Relaxed ) ;
100- marker:: Python :: with_gil ( |py| -> PyResult < Py < PyAny > > {
99+ marker:: Python :: with_gil ( |py| -> crate :: Result < String > {
101100 let arg = pyo3:: types:: PyTuple :: new ( py, payload. args ) ?;
102101 let map = FUNCTION_MAP
103102 . lock ( )
104103 . map_err ( |msg| PyErr :: new :: < PyBaseException , _ > ( msg. to_string ( ) ) ) ?;
105104 match map. get ( & payload. function_name ) {
106105 Some ( app) => {
107106 // dbg!(&arg);
108- let res = app. call1 ( py, arg) ;
107+ let res = app. call1 ( py, arg) ? ;
109108 // dbg!(&res);
110- res
109+ Ok ( res. to_string ( ) )
111110 }
112- _ => Err ( pyo3 :: exceptions :: PyException :: new_err ( format ! (
111+ _ => Err ( Error :: String ( format ! (
113112 "{} not found" ,
114113 payload. function_name
115114 ) ) ) ,
116115 }
117116 } )
118117}
119118
120- pub fn read_variable ( payload : StringRequest ) -> PyResult < String > {
121- marker:: Python :: with_gil ( |py| -> PyResult < String > {
119+ pub fn read_variable ( payload : StringRequest ) -> crate :: Result < String > {
120+ marker:: Python :: with_gil ( |py| -> crate :: Result < String > {
122121 let globals = GLOBALS . lock ( ) . unwrap ( ) . clone_ref ( py) . into_bound ( py) ;
123122
124123 let var_dot_split: Vec < & str > = payload. value . split ( "." ) . collect ( ) ;
@@ -130,10 +129,7 @@ pub fn read_variable(payload: StringRequest) -> PyResult<String> {
130129 Ok ( var. to_string ( ) )
131130 }
132131 } else {
133- Err ( pyo3:: exceptions:: PyException :: new_err ( format ! (
134- "{} not set" ,
135- & payload. value
136- ) ) )
132+ Err ( Error :: String ( format ! ( "{} not set" , & payload. value) ) )
137133 }
138134 } )
139135}
0 commit comments