aboutsummaryrefslogtreecommitdiff
path: root/src/wrapper/descriptors
diff options
context:
space:
mode:
Diffstat (limited to 'src/wrapper/descriptors')
-rw-r--r--src/wrapper/descriptors/class_desc.rs39
-rw-r--r--src/wrapper/descriptors/desc.rs17
-rw-r--r--src/wrapper/descriptors/exception_desc.rs47
-rw-r--r--src/wrapper/descriptors/field_desc.rs29
-rw-r--r--src/wrapper/descriptors/method_desc.rs39
-rw-r--r--src/wrapper/descriptors/mod.rs14
6 files changed, 185 insertions, 0 deletions
diff --git a/src/wrapper/descriptors/class_desc.rs b/src/wrapper/descriptors/class_desc.rs
new file mode 100644
index 0000000..9b2e46b
--- /dev/null
+++ b/src/wrapper/descriptors/class_desc.rs
@@ -0,0 +1,39 @@
+use crate::{
+ descriptors::Desc,
+ errors::*,
+ objects::{AutoLocal, GlobalRef, JClass, JObject},
+ strings::JNIString,
+ JNIEnv,
+};
+
+impl<'a, T> Desc<'a, JClass<'a>> for T
+where
+ T: Into<JNIString>,
+{
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JClass<'a>> {
+ env.find_class(self)
+ }
+}
+
+impl<'a, 'b> Desc<'a, JClass<'a>> for JObject<'b> {
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JClass<'a>> {
+ env.get_object_class(self)
+ }
+}
+
+/// This conversion assumes that the `GlobalRef` is a pointer to a class object.
+impl<'a, 'b> Desc<'a, JClass<'b>> for &'b GlobalRef {
+ fn lookup(self, _: &JNIEnv<'a>) -> Result<JClass<'b>> {
+ Ok(self.as_obj().into())
+ }
+}
+
+/// This conversion assumes that the `AutoLocal` is a pointer to a class object.
+impl<'a, 'b, 'c> Desc<'a, JClass<'b>> for &'b AutoLocal<'c, '_>
+where
+ 'c: 'b,
+{
+ fn lookup(self, _: &JNIEnv<'a>) -> Result<JClass<'b>> {
+ Ok(self.as_obj().into())
+ }
+}
diff --git a/src/wrapper/descriptors/desc.rs b/src/wrapper/descriptors/desc.rs
new file mode 100644
index 0000000..2d7fd9d
--- /dev/null
+++ b/src/wrapper/descriptors/desc.rs
@@ -0,0 +1,17 @@
+use crate::{errors::*, JNIEnv};
+
+/// Trait for things that can be looked up through the JNI via a descriptor.
+/// This will be something like the fully-qualified class name
+/// `java/lang/String` or a tuple containing a class descriptor, method name,
+/// and method signature. For convenience, this is also implemented for the
+/// concrete types themselves in addition to their descriptors.
+pub trait Desc<'a, T> {
+ /// Look up the concrete type from the JVM.
+ fn lookup(self, _: &JNIEnv<'a>) -> Result<T>;
+}
+
+impl<'a, T> Desc<'a, T> for T {
+ fn lookup(self, _: &JNIEnv<'a>) -> Result<T> {
+ Ok(self)
+ }
+}
diff --git a/src/wrapper/descriptors/exception_desc.rs b/src/wrapper/descriptors/exception_desc.rs
new file mode 100644
index 0000000..71ccf68
--- /dev/null
+++ b/src/wrapper/descriptors/exception_desc.rs
@@ -0,0 +1,47 @@
+use crate::{
+ descriptors::Desc,
+ errors::*,
+ objects::{JClass, JObject, JThrowable, JValue},
+ strings::JNIString,
+ JNIEnv,
+};
+
+const DEFAULT_EXCEPTION_CLASS: &str = "java/lang/RuntimeException";
+
+impl<'a, 'c, C, M> Desc<'a, JThrowable<'a>> for (C, M)
+where
+ C: Desc<'a, JClass<'c>>,
+ M: Into<JNIString>,
+{
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JThrowable<'a>> {
+ let jmsg: JObject = env.new_string(self.1)?.into();
+ let obj: JThrowable = env
+ .new_object(self.0, "(Ljava/lang/String;)V", &[JValue::from(jmsg)])?
+ .into();
+ Ok(obj)
+ }
+}
+
+impl<'a> Desc<'a, JThrowable<'a>> for Exception {
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JThrowable<'a>> {
+ (self.class, self.msg).lookup(env)
+ }
+}
+
+impl<'a, 'b> Desc<'a, JThrowable<'a>> for &'b str {
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JThrowable<'a>> {
+ (DEFAULT_EXCEPTION_CLASS, self).lookup(env)
+ }
+}
+
+impl<'a> Desc<'a, JThrowable<'a>> for String {
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JThrowable<'a>> {
+ (DEFAULT_EXCEPTION_CLASS, self).lookup(env)
+ }
+}
+
+impl<'a, 'b> Desc<'a, JThrowable<'a>> for JNIString {
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JThrowable<'a>> {
+ (DEFAULT_EXCEPTION_CLASS, self).lookup(env)
+ }
+}
diff --git a/src/wrapper/descriptors/field_desc.rs b/src/wrapper/descriptors/field_desc.rs
new file mode 100644
index 0000000..cdaf908
--- /dev/null
+++ b/src/wrapper/descriptors/field_desc.rs
@@ -0,0 +1,29 @@
+use crate::{
+ descriptors::Desc,
+ errors::*,
+ objects::{JClass, JFieldID, JStaticFieldID},
+ strings::JNIString,
+ JNIEnv,
+};
+
+impl<'a, 'c, T, U, V> Desc<'a, JFieldID<'a>> for (T, U, V)
+where
+ T: Desc<'a, JClass<'c>>,
+ U: Into<JNIString>,
+ V: Into<JNIString>,
+{
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JFieldID<'a>> {
+ env.get_field_id(self.0, self.1, self.2)
+ }
+}
+
+impl<'a, 'c, T, U, V> Desc<'a, JStaticFieldID<'a>> for (T, U, V)
+where
+ T: Desc<'a, JClass<'c>>,
+ U: Into<JNIString>,
+ V: Into<JNIString>,
+{
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JStaticFieldID<'a>> {
+ env.get_static_field_id(self.0, self.1, self.2)
+ }
+}
diff --git a/src/wrapper/descriptors/method_desc.rs b/src/wrapper/descriptors/method_desc.rs
new file mode 100644
index 0000000..bbd2651
--- /dev/null
+++ b/src/wrapper/descriptors/method_desc.rs
@@ -0,0 +1,39 @@
+use crate::{
+ descriptors::Desc,
+ errors::*,
+ objects::{JClass, JMethodID, JStaticMethodID},
+ strings::JNIString,
+ JNIEnv,
+};
+
+impl<'a, 'c, T, U, V> Desc<'a, JMethodID<'a>> for (T, U, V)
+where
+ T: Desc<'a, JClass<'c>>,
+ U: Into<JNIString>,
+ V: Into<JNIString>,
+{
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JMethodID<'a>> {
+ env.get_method_id(self.0, self.1, self.2)
+ }
+}
+
+impl<'a, 'c, T, Signature> Desc<'a, JMethodID<'a>> for (T, Signature)
+where
+ T: Desc<'a, JClass<'c>>,
+ Signature: Into<JNIString>,
+{
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JMethodID<'a>> {
+ (self.0, "<init>", self.1).lookup(env)
+ }
+}
+
+impl<'a, 'c, T, U, V> Desc<'a, JStaticMethodID<'a>> for (T, U, V)
+where
+ T: Desc<'a, JClass<'c>>,
+ U: Into<JNIString>,
+ V: Into<JNIString>,
+{
+ fn lookup(self, env: &JNIEnv<'a>) -> Result<JStaticMethodID<'a>> {
+ env.get_static_method_id(self.0, self.1, self.2)
+ }
+}
diff --git a/src/wrapper/descriptors/mod.rs b/src/wrapper/descriptors/mod.rs
new file mode 100644
index 0000000..e2fc230
--- /dev/null
+++ b/src/wrapper/descriptors/mod.rs
@@ -0,0 +1,14 @@
+mod desc;
+pub use self::desc::*;
+
+mod class_desc;
+pub use self::class_desc::*;
+
+mod method_desc;
+pub use self::method_desc::*;
+
+mod field_desc;
+pub use self::field_desc::*;
+
+mod exception_desc;
+pub use self::exception_desc::*;