From 1006aa34dfca54cd1141d7b7964684620fc49a4e Mon Sep 17 00:00:00 2001 From: LostLuma Date: Fri, 25 Oct 2024 22:45:31 +0200 Subject: [PATCH] Improve and deduplicate Rust code --- src/main/rust/bridge.rs | 29 +++++++++++++---------------- src/main/rust/lib.rs | 36 +++++++++++++----------------------- src/main/rust/util.rs | 18 ++++++++++++++++-- 3 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/main/rust/bridge.rs b/src/main/rust/bridge.rs index 1089675..e8ad3bc 100644 --- a/src/main/rust/bridge.rs +++ b/src/main/rust/bridge.rs @@ -3,10 +3,9 @@ use jni::{ sys::jlong, JNIEnv, }; +use starship_battery::{Battery, Manager}; -use crate::{ - create_manager, drop_battery, drop_manager, get_batteries, throw_io_exception, update_battery, -}; +use crate::{create_manager, get_batteries, update_battery, util::drop_box}; #[no_mangle] pub extern "system" fn Java_net_lostluma_battery_impl_ManagerImpl_create<'a>( @@ -14,12 +13,11 @@ pub extern "system" fn Java_net_lostluma_battery_impl_ManagerImpl_create<'a>( _class: JClass<'a>, ) -> jlong { match create_manager() { - Ok(value) => value, - Err(error) => { - throw_io_exception(&mut env, error); - jlong::default() - } + Ok(ptr) => return ptr, + Err(error) => error.throw(&mut env), } + + jlong::default() } #[no_mangle] @@ -28,12 +26,11 @@ pub extern "system" fn Java_net_lostluma_battery_impl_ManagerImpl_batteries0<'a> this: JObject<'a>, ) -> JObjectArray<'a> { match get_batteries(&mut env, &this) { - Ok(value) => value, - Err(error) => { - throw_io_exception(&mut env, error); - JObjectArray::default() - } + Ok(batteries) => return batteries, + Err(error) => error.throw(&mut env), } + + JObjectArray::default() } #[no_mangle] @@ -42,7 +39,7 @@ pub extern "system" fn Java_net_lostluma_battery_impl_ManagerImpl_drop<'a>( _this: JObject<'a>, ptr: jlong, ) { - drop_manager(ptr); + drop_box::(ptr); } #[no_mangle] @@ -51,7 +48,7 @@ pub extern "system" fn Java_net_lostluma_battery_impl_BatteryImpl_update0<'a>( this: JObject<'a>, ) { if let Err(error) = update_battery(&mut env, &this) { - throw_io_exception(&mut env, error); + error.throw(&mut env); } } @@ -61,5 +58,5 @@ pub extern "system" fn Java_net_lostluma_battery_impl_ManagerImpl_dropBattery<'a _this: JObject<'a>, ptr: jlong, ) { - drop_battery(ptr) + drop_box::(ptr); } diff --git a/src/main/rust/lib.rs b/src/main/rust/lib.rs index b987497..3b5cc08 100644 --- a/src/main/rust/lib.rs +++ b/src/main/rust/lib.rs @@ -12,7 +12,7 @@ use starship_battery::{ }, Battery, Manager, }; -use util::{as_descriptor, get_enum_member, get_ptr, ToJString}; +use util::{as_descriptor, get_enum_member, into_box, pull_box, ToJString}; const STRING_CLASS: &str = "java/lang/String"; const IO_EXCEPTION_CLASS: &str = "java/io/IOException"; @@ -30,6 +30,13 @@ struct Error { message: String, // Used as IOError message } +impl Error { + fn throw(self, env: &mut JNIEnv) { + env.throw_new(IO_EXCEPTION_CLASS, self.message) + .expect("throw exception"); + } +} + impl From for Error { fn from(value: jni::errors::Error) -> Self { Error { @@ -50,12 +57,11 @@ type Result = result::Result; fn create_manager() -> Result { let manager = Manager::new()?; - Ok(Box::into_raw(Box::from(manager)) as jlong) + Ok(into_box(manager) as jlong) } fn get_batteries<'a>(env: &mut JNIEnv<'a>, this: &JObject<'a>) -> Result> { - let ptr = get_ptr(env, this)?; - let manager = unsafe { &mut *(ptr as *mut Manager) }; + let manager = pull_box::(env, this)?; let mut count = 0; let mut batteries: Vec = Vec::new(); @@ -78,11 +84,6 @@ fn get_batteries<'a>(env: &mut JNIEnv<'a>, this: &JObject<'a>) -> Result(ptr: jlong) { - #[allow(unused_variables)] - let manager = unsafe { Box::from_raw(ptr as *mut Manager) }; -} - fn create_battery<'a>( env: &mut JNIEnv<'a>, parent: &JObject<'a>, @@ -94,8 +95,7 @@ fn create_battery<'a>( let model = battery.model().to_jstring(env)?; let serial_number = battery.serial_number().to_jstring(env)?; - let ptr = Box::into_raw(Box::from(battery)) as jlong; - + let ptr = into_box(battery); let class = env.find_class(BATTERY_CLASS)?; let object = env.new_object( @@ -112,8 +112,8 @@ fn update_battery<'a>(env: &mut JNIEnv<'a>, this: &JObject<'a>) -> Result<()> { .get_field(this, "manager", as_descriptor(MANAGER_CLASS))? .l()?; - let battery = unsafe { &mut *(get_ptr(env, this)? as *mut Battery) }; - let manager = unsafe { &mut *(get_ptr(env, &parent)? as *mut Manager) }; + let battery = pull_box::(env, this)?; + let manager = pull_box::(env, &parent)?; manager.refresh(battery)?; @@ -166,13 +166,3 @@ fn update_battery<'a>(env: &mut JNIEnv<'a>, this: &JObject<'a>) -> Result<()> { Ok(()) } - -fn drop_battery<'a>(ptr: jlong) { - #[allow(unused_variables)] - let battery = unsafe { Box::from_raw(ptr as *mut Battery) }; -} - -fn throw_io_exception<'a>(env: &mut JNIEnv<'a>, error: Error) { - env.throw_new(IO_EXCEPTION_CLASS, error.message) - .expect("throw exception"); -} diff --git a/src/main/rust/util.rs b/src/main/rust/util.rs index 9875c3b..d3dc42c 100644 --- a/src/main/rust/util.rs +++ b/src/main/rust/util.rs @@ -10,8 +10,22 @@ pub fn as_descriptor(class: &str) -> String { format!("L{class};") } -pub fn get_ptr<'a>(env: &mut JNIEnv<'a>, this: &JObject<'a>) -> Result { - Ok(env.get_field(this, "ptr", "J")?.try_into()?) +pub fn into_box(t: T) -> jlong { + Box::into_raw(Box::from(t)) as jlong +} + +pub fn drop_box(ptr: jlong) { + #[allow(unused_variables)] + let value = unsafe { Box::from_raw(ptr as *mut T) }; +} + +fn get_pointer(env: &mut JNIEnv, object: &JObject) -> Result { + Ok(env.get_field(object, "ptr", "J")?.j()?) +} + +pub fn pull_box<'r, T>(env: &mut JNIEnv, object: &JObject) -> Result<&'r mut T> { + let pointer = get_pointer(env, object)?; + Ok(unsafe { &mut *(pointer as *mut T) }) } pub fn get_enum_member<'a>(