/
jni_helpers.rs
87 lines (80 loc) · 2.63 KB
/
jni_helpers.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use crate::Runtime;
use jni::{
errors::Error as JniError,
objects::{JObject, JValue},
JNIEnv,
};
use serde_json::Value as JsonValue;
use tauri_runtime::RuntimeHandle;
fn json_to_java<'a, R: Runtime>(
env: JNIEnv<'a>,
activity: JObject<'a>,
runtime_handle: &R::Handle,
json: &JsonValue,
) -> Result<(&'static str, JValue<'a>), JniError> {
let (class, v) = match json {
JsonValue::Null => ("Ljava/lang/Object;", JObject::null().into()),
JsonValue::Bool(val) => ("Z", (*val).into()),
JsonValue::Number(val) => {
if let Some(v) = val.as_i64() {
("J", v.into())
} else if let Some(v) = val.as_f64() {
("D", v.into())
} else {
("Ljava/lang/Object;", JObject::null().into())
}
}
JsonValue::String(val) => (
"Ljava/lang/Object;",
JObject::from(env.new_string(&val)?).into(),
),
JsonValue::Array(val) => {
let js_array_class = runtime_handle.find_class(env, activity, "app/tauri/plugin/JSArray")?;
let data = env.new_object(js_array_class, "()V", &[])?;
for v in val {
let (signature, val) = json_to_java::<R>(env, activity, runtime_handle, v)?;
env.call_method(
data,
"put",
format!("({signature})Lorg/json/JSONArray;"),
&[val],
)?;
}
("Ljava/lang/Object;", data.into())
}
JsonValue::Object(val) => {
let js_object_class =
runtime_handle.find_class(env, activity, "app/tauri/plugin/JSObject")?;
let data = env.new_object(js_object_class, "()V", &[])?;
for (key, value) in val {
let (signature, val) = json_to_java::<R>(env, activity, runtime_handle, value)?;
env.call_method(
data,
"put",
format!("(Ljava/lang/String;{signature})Lapp/tauri/plugin/JSObject;"),
&[env.new_string(&key)?.into(), val],
)?;
}
("Ljava/lang/Object;", data.into())
}
};
Ok((class, v))
}
pub fn to_jsobject<'a, R: Runtime>(
env: JNIEnv<'a>,
activity: JObject<'a>,
runtime_handle: &R::Handle,
json: &JsonValue,
) -> Result<JValue<'a>, JniError> {
if let JsonValue::Object(_) = json {
json_to_java::<R>(env, activity, runtime_handle, json).map(|(_class, data)| data)
} else {
// currently the Kotlin lib cannot handle nulls or raw values, it must be an object
let js_object_class = runtime_handle.find_class(env, activity, "app/tauri/plugin/JSObject")?;
let data = env.new_object(js_object_class, "()V", &[])?;
Ok(data.into())
}
}