Skip to content

Commit 145e645

Browse files
committed
fixing issues after testing pyo3 feature
1 parent a656931 commit 145e645

8 files changed

Lines changed: 56 additions & 52 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ serde_json = "1.0.136"
3131
tauri-plugin = { version = "2", features = ["build"] }
3232

3333
[features]
34+
# default = ["pyo3"] # enable to use pyo3 instead of rustpython
3435
pyo3 = ["dep:pyo3"]

src/desktop.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@
44
// git clone https://github.com/marcomq/tauri-plugin-python
55

66
use serde::de::DeserializeOwned;
7-
use tauri::{ plugin::PluginApi, AppHandle, Runtime};
7+
use tauri::{plugin::PluginApi, AppHandle, Runtime};
88

9+
#[cfg(feature = "pyo3")]
10+
use crate::py_lib_pyo3 as py_lib;
11+
#[cfg(not(feature = "pyo3"))]
912
use crate::py_lib;
1013

1114
/// Access to the python plugin APIs.
1215
pub struct Python<R: Runtime>(AppHandle<R>);
1316

1417
fn read_main_py<'a>() -> String {
15-
let py_file_path = std::env::current_dir().unwrap().join("src-python").join("main.py");
18+
let py_file_path = std::env::current_dir()
19+
.unwrap()
20+
.join("src-python")
21+
.join("main.py");
1622
std::fs::read_to_string(py_file_path).unwrap_or_default()
1723
// include_str!(concat!(env!("PWD"), "/src-tauri/src-python/main.py"))
1824
}

src/error.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ pub type Result<T> = std::result::Result<T, Error>;
1111

1212
#[derive(Debug, thiserror::Error)]
1313
pub enum Error {
14+
#[error("Error: {0}")]
15+
String(String),
1416
#[error(transparent)]
1517
Io(#[from] std::io::Error),
1618
#[cfg(mobile)]
@@ -27,10 +29,9 @@ impl Serialize for Error {
2729
}
2830
}
2931

30-
// probably not the best solution - please optimize :)
3132
impl From<&str> for Error {
3233
fn from(error: &str) -> Self {
33-
std::io::Error::new(std::io::ErrorKind::Other, error).into()
34+
Error::String(error.into())
3435
}
3536
}
3637

@@ -39,7 +40,7 @@ impl From<rustpython_vm::PyRef<rustpython_vm::builtins::PyBaseException>> for Er
3940
fn from(error: rustpython_vm::PyRef<rustpython_vm::builtins::PyBaseException>) -> Self {
4041
let msg = format!("{:?}", &error);
4142
println!("error: {}", &msg);
42-
std::io::Error::new(std::io::ErrorKind::Other, msg).into()
43+
Error::String(msg)
4344
}
4445
}
4546

@@ -48,7 +49,7 @@ impl From<PyErr> for Error {
4849
fn from(error: PyErr) -> Self {
4950
let msg = error.to_string();
5051
println!("error: {}", &msg);
51-
std::io::Error::new(std::io::ErrorKind::Other, msg).into()
52+
Error::String(msg)
5253
}
5354
}
5455

src/lib.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ mod models;
2020
mod py_lib;
2121
#[cfg(feature = "pyo3")]
2222
mod py_lib_pyo3;
23+
#[cfg(feature = "pyo3")]
24+
use py_lib_pyo3 as py_lib;
25+
2326

2427
pub use error::{Error, Result};
2528
use models::*;
@@ -51,10 +54,8 @@ impl<R: Runtime, T: Manager<R>> crate::PythonExt<R> for T {
5154
Ok(StringResponse { value: "Ok".into() })
5255
}
5356
fn call_function(&self, payload: RunRequest) -> crate::Result<StringResponse> {
54-
let py_res = py_lib::call_function(payload)?;
55-
Ok(StringResponse {
56-
value: py_res.to_string(),
57-
})
57+
let py_res: String = py_lib::call_function(payload)?.into();
58+
Ok(StringResponse { value: py_res })
5859
}
5960
fn read_variable(&self, payload: StringRequest) -> crate::Result<StringResponse> {
6061
let py_res = py_lib::read_variable(payload)?;

src/mobile.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use serde::de::DeserializeOwned;
77
use tauri::{
88
path::BaseDirectory,
99
plugin::{PluginApi, PluginHandle},
10-
AppHandle, Runtime, Manager
10+
AppHandle, Manager, Runtime,
1111
};
1212

1313
use crate::models::*;

src/models.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ pub struct StringRequest {
1313

1414
#[cfg(feature = "pyo3")]
1515
#[derive(Debug, Serialize, Deserialize, pyo3::IntoPyObject)]
16-
#[cfg(not(feature = "pyo3"))]
17-
#[derive(Debug, Serialize, Deserialize)]
1816
#[serde(untagged)]
1917
pub enum JsMany {
2018
Bool(bool),

src/py_lib.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,14 @@
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;
86
use std::sync::atomic::AtomicBool;
97
use std::{collections::HashSet, sync::Mutex};
108

11-
use rustpython_vm::{py_serde, PyResult};
9+
use rustpython_vm::py_serde;
1210

1311
use lazy_static::lazy_static;
1412

15-
use crate::models::*;
13+
use crate::{models::*, Error};
1614

1715
fn create_globals() -> rustpython_vm::scope::Scope {
1816
rustpython_vm::Interpreter::without_stdlib(Default::default())
@@ -57,19 +55,22 @@ pub fn register_function(payload: RegisterRequest) -> crate::Result<()> {
5755
}
5856

5957
pub fn register_function_str(fn_name: String, number_of_args: Option<u8>) -> crate::Result<()> {
58+
if INIT_BLOCKED.load(std::sync::atomic::Ordering::Relaxed) {
59+
return Err("Cannot register after function called".into());
60+
}
6061
rustpython_vm::Interpreter::without_stdlib(Default::default()).enter(|vm| {
6162
GLOBALS.globals.get_item(&fn_name, vm).unwrap();
6263
FUNCTION_MAP.lock().unwrap().insert(fn_name);
6364
Ok(())
6465
})
6566
}
6667
pub fn call_function(payload: RunRequest) -> crate::Result<String> {
68+
INIT_BLOCKED.store(true, std::sync::atomic::Ordering::Relaxed);
6769
let function_name = payload.function_name;
6870
if FUNCTION_MAP.lock().unwrap().get(&function_name).is_none() {
69-
Err(std::io::Error::new(
70-
std::io::ErrorKind::Other,
71-
format!("Function {function_name} has not been registered yet"),
72-
))?;
71+
return Err(Error::String(format!(
72+
"Function {function_name} has not been registered yet"
73+
)));
7374
}
7475
rustpython_vm::Interpreter::without_stdlib(Default::default()).enter(|vm| {
7576
let posargs: Vec<_> = payload

src/py_lib_pyo3.rs

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
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;
86
use std::sync::atomic::AtomicBool;
97
use std::{collections::HashMap, ffi::CString, sync::Mutex};
108

@@ -14,7 +12,7 @@ use pyo3::types::{PyAnyMethods, PyDictMethods, PyList, PyListMethods};
1412
use pyo3::PyErr;
1513
use pyo3::{marker, types::PyDict, Py, PyAny, PyResult};
1614

17-
use crate::models::*;
15+
use crate::{models::*, Error};
1816

1917
lazy_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+
2630
pub 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

Comments
 (0)