java_oxide/
jni_type.rs

1use jni_sys::*;
2use std::ffi::CStr;
3
4/// JNI bindings rely on this type being accurate.
5///
6/// # Safety
7///
8/// **unsafe**: Passing the wrong type can cause unsoundness, since the code that interacts with JNI blindly trusts it's correct.
9///
10/// Why the awkward callback style instead of returning `&'static CStr`?  Arrays of arrays may need to dynamically
11/// construct their type strings, which would need to leak.  Worse, we can't easily intern those strings via
12/// lazy_static without running into:
13///
14/// ```text
15/// error[E0401]: can't use generic parameters from outer function
16/// ```
17pub unsafe trait JniType {
18    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R;
19}
20
21unsafe impl JniType for () {
22    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R {
23        callback(c"V")
24    }
25}
26unsafe impl JniType for bool {
27    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R {
28        callback(c"Z")
29    }
30}
31unsafe impl JniType for jbyte {
32    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R {
33        callback(c"B")
34    }
35}
36unsafe impl JniType for jchar {
37    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R {
38        callback(c"C")
39    }
40}
41unsafe impl JniType for jshort {
42    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R {
43        callback(c"S")
44    }
45}
46unsafe impl JniType for jint {
47    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R {
48        callback(c"I")
49    }
50}
51unsafe impl JniType for jlong {
52    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R {
53        callback(c"J")
54    }
55}
56unsafe impl JniType for jfloat {
57    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R {
58        callback(c"F")
59    }
60}
61unsafe impl JniType for jdouble {
62    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R {
63        callback(c"D")
64    }
65}
66unsafe impl JniType for &CStr {
67    fn static_with_jni_type<R>(callback: impl FnOnce(&CStr) -> R) -> R {
68        callback(c"Ljava/lang/String;")
69    }
70}