java_spaghetti/
lib.rs

1//! Common glue code between Rust and JNI, used in autogenerated `java-spaghetti` glue code.
2//!
3//! See also the [Android JNI tips](https://developer.android.com/training/articles/perf-jni) documentation as well as the
4//! [Java Native Interface Specification](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html).
5
6use std::fmt;
7use std::ptr::null_mut;
8
9/// public jni-sys reexport.
10pub use ::jni_sys as sys;
11use sys::{jobject, jvalue};
12
13mod refs {
14    mod arg;
15    mod global;
16    mod local;
17    mod ref_;
18    mod return_;
19
20    pub use arg::*;
21    pub use global::*;
22    pub use local::*;
23    pub use ref_::*;
24    pub use return_::*;
25}
26
27mod array;
28mod as_jvalue;
29mod env;
30mod jni_type;
31mod string_chars;
32mod vm;
33
34pub use array::*;
35pub use as_jvalue::*;
36pub use env::*;
37pub use jni_type::JniType;
38pub use refs::*;
39pub use string_chars::*;
40pub use vm::*;
41
42/// Error returned on failed `.cast()`.`
43#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
44pub struct CastError;
45
46impl std::error::Error for CastError {}
47impl fmt::Display for CastError {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        f.write_str("Cast failed")
50    }
51}
52
53/// A marker type indicating this is a valid exception type that all exceptions thrown by java should be compatible with
54pub trait ThrowableType: ReferenceType {}
55
56/// You should generally not be interacting with this type directly, but it must be public for codegen.
57/// This is hideously unsafe to implement:
58///
59/// 1) You assert the type is a #[repr(transparent)] wrapper around ObjectAndEnv.
60/// 2) You assert the type cannot exist with a dangling object or env.
61///     2.1) Do not implement Copy or Clone.
62///     2.2) Do not allow value access.
63///     2.3) Do not allow &mut T access.
64///     2.4) Only allow &T access, which cannot be moved from.
65#[doc(hidden)]
66pub unsafe trait ReferenceType: JniType + 'static {}
67
68/// Marker trait indicating `Self` can be assigned to `T`.
69///
70/// This is true when `T` is a superclass or superinterface of `Self`.
71pub unsafe trait AssignableTo<T: ReferenceType>: ReferenceType {}
72
73/// A type is always assignable to itself.
74unsafe impl<T: ReferenceType> AssignableTo<T> for T {}
75
76#[repr(C)] // Given how frequently we transmute to/from this, we'd better keep a consistent layout.
77#[doc(hidden)] // You should generally not be interacting with this type directly, but it must be public for codegen.
78#[derive(Copy, Clone)]
79pub struct ObjectAndEnv {
80    pub object: jni_sys::jobject,
81    pub env: *mut jni_sys::JNIEnv,
82}
83
84pub unsafe trait AsArg<T>: Sized {
85    fn as_arg(&self) -> jobject;
86    fn as_arg_jvalue(&self) -> jvalue {
87        jvalue { l: self.as_arg() }
88    }
89}
90
91#[derive(Copy, Clone, PartialEq, Eq, Debug)]
92pub struct Null;
93
94unsafe impl<T: ReferenceType, U: AsArg<T>> AsArg<T> for &U {
95    fn as_arg(&self) -> jobject {
96        U::as_arg(self)
97    }
98}
99
100unsafe impl<T: ReferenceType, U: AsArg<T>> AsArg<T> for &mut U {
101    fn as_arg(&self) -> jobject {
102        U::as_arg(self)
103    }
104}
105
106unsafe impl<T: ReferenceType> AsArg<T> for Null {
107    fn as_arg(&self) -> jobject {
108        null_mut()
109    }
110}
111
112unsafe impl<T: ReferenceType, U: AssignableTo<T>> AsArg<T> for Ref<'_, U> {
113    fn as_arg(&self) -> jobject {
114        self.as_raw()
115    }
116}
117
118unsafe impl<T: ReferenceType, U: AssignableTo<T>> AsArg<T> for Option<Ref<'_, U>> {
119    fn as_arg(&self) -> jobject {
120        self.map(|r| r.as_raw()).unwrap_or(null_mut())
121    }
122}
123
124unsafe impl<T: ReferenceType, U: AssignableTo<T>> AsArg<T> for Option<&Ref<'_, U>> {
125    fn as_arg(&self) -> jobject {
126        self.map(|r| r.as_raw()).unwrap_or(null_mut())
127    }
128}
129
130unsafe impl<T: ReferenceType, U: AssignableTo<T>> AsArg<T> for Local<'_, U> {
131    fn as_arg(&self) -> jobject {
132        self.as_raw()
133    }
134}
135
136unsafe impl<T: ReferenceType, U: AssignableTo<T>> AsArg<T> for Option<Local<'_, U>> {
137    fn as_arg(&self) -> jobject {
138        self.as_ref().map(|r| r.as_raw()).unwrap_or(null_mut())
139    }
140}
141
142unsafe impl<T: ReferenceType, U: AssignableTo<T>> AsArg<T> for Option<&Local<'_, U>> {
143    fn as_arg(&self) -> jobject {
144        self.map(|r| r.as_raw()).unwrap_or(null_mut())
145    }
146}
147
148unsafe impl<T: ReferenceType, U: AssignableTo<T>> AsArg<T> for Global<U> {
149    fn as_arg(&self) -> jobject {
150        self.as_raw()
151    }
152}
153
154unsafe impl<T: ReferenceType, U: AssignableTo<T>> AsArg<T> for Option<Global<U>> {
155    fn as_arg(&self) -> jobject {
156        self.as_ref().map(|r| r.as_raw()).unwrap_or(null_mut())
157    }
158}
159
160unsafe impl<T: ReferenceType, U: AssignableTo<T>> AsArg<T> for Option<&Global<U>> {
161    fn as_arg(&self) -> jobject {
162        self.map(|r| r.as_raw()).unwrap_or(null_mut())
163    }
164}