Skip to content

Commit

Permalink
Improve and deduplicate Rust code
Browse files Browse the repository at this point in the history
  • Loading branch information
LostLuma committed Oct 25, 2024
1 parent 362f207 commit 1006aa3
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 41 deletions.
29 changes: 13 additions & 16 deletions src/main/rust/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,21 @@ 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>(
mut env: JNIEnv<'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]
Expand All @@ -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]
Expand All @@ -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::<Manager>(ptr);
}

#[no_mangle]
Expand All @@ -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);
}
}

Expand All @@ -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::<Battery>(ptr);
}
36 changes: 13 additions & 23 deletions src/main/rust/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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<jni::errors::Error> for Error {
fn from(value: jni::errors::Error) -> Self {
Error {
Expand All @@ -50,12 +57,11 @@ type Result<T> = result::Result<T, Error>;

fn create_manager() -> Result<i64> {
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<JObjectArray<'a>> {
let ptr = get_ptr(env, this)?;
let manager = unsafe { &mut *(ptr as *mut Manager) };
let manager = pull_box::<Manager>(env, this)?;

let mut count = 0;
let mut batteries: Vec<Battery> = Vec::new();
Expand All @@ -78,11 +84,6 @@ fn get_batteries<'a>(env: &mut JNIEnv<'a>, this: &JObject<'a>) -> Result<JObject
Ok(array)
}

fn drop_manager<'a>(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>,
Expand All @@ -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(
Expand All @@ -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::<Battery>(env, this)?;
let manager = pull_box::<Manager>(env, &parent)?;

manager.refresh(battery)?;

Expand Down Expand Up @@ -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");
}
18 changes: 16 additions & 2 deletions src/main/rust/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<jlong> {
Ok(env.get_field(this, "ptr", "J")?.try_into()?)
pub fn into_box<T>(t: T) -> jlong {
Box::into_raw(Box::from(t)) as jlong
}

pub fn drop_box<T>(ptr: jlong) {
#[allow(unused_variables)]
let value = unsafe { Box::from_raw(ptr as *mut T) };
}

fn get_pointer(env: &mut JNIEnv, object: &JObject) -> Result<jlong> {
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>(
Expand Down

0 comments on commit 1006aa3

Please sign in to comment.