Skip to content

Commit

Permalink
Manual IntoJava impl to skip locked_down field
Browse files Browse the repository at this point in the history
Here we manually implement the `IntoJava` trait of jnix to skip the
`locked_down` field of `TunnelState::Disconnected` as the derive macro
currently does not support skipping fields of struct variants in and
enum. It was decided that this solution is the preferred to updating the
macro since the jnix crate will be dropped once android implements gRPC.
  • Loading branch information
Serock3 committed Jan 18, 2024
1 parent b2c65f7 commit 3b042e8
Showing 1 changed file with 113 additions and 4 deletions.
117 changes: 113 additions & 4 deletions mullvad-types/src/states.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::location::GeoIpLocation;
#[cfg(target_os = "android")]
use jnix::IntoJava;
use serde::{Deserialize, Serialize};
use std::fmt;
use talpid_types::{
Expand Down Expand Up @@ -31,8 +29,6 @@ impl fmt::Display for TargetState {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(tag = "state", content = "details")]
#[cfg_attr(target_os = "android", derive(IntoJava))]
#[cfg_attr(target_os = "android", jnix(package = "net.mullvad.mullvadvpn.model"))]
pub enum TunnelState {
Disconnected {
location: Option<GeoIpLocation>,
Expand Down Expand Up @@ -67,3 +63,116 @@ impl TunnelState {
matches!(self, TunnelState::Disconnected { .. })
}
}

#[cfg(target_os = "android")]
// Here we manually implement the `IntoJava` trait of jnix to skip the `locked_down` field of
// `TunnelState::Disconnected`. The derive macro currently does not support skipping fields in
// struct variants of enums. It was decided that this solution is the preferred to updating the
// macro since the jnix crate will be dropped once android implements gRPC.
impl<'borrow, 'env> jnix::IntoJava<'borrow, 'env> for TunnelState
where
'env: 'borrow,
{
const JNI_SIGNATURE: &'static str = "Lnet/mullvad/mullvadvpn/model/TunnelState;";
type JavaType = jnix::jni::objects::AutoLocal<'env, 'borrow>;
#[allow(non_snake_case)]
fn into_java(self, env: &'borrow jnix::JnixEnv<'env>) -> Self::JavaType {
match self {
Self::Disconnected {
location,
locked_down: _,
} => {
let constructor_signature = format!("({})V", location.jni_signature());

let location_java = location.into_java(env);
let parameters = [jnix::AsJValue::as_jvalue(&location_java)];

let class = env.get_class("net/mullvad/mullvadvpn/model/TunnelState$Disconnected");

let object = env
.new_object(&class, constructor_signature, &parameters)
.expect(
"Failed to convert TunnelState::Disconnected Rust type into net.mullvad.mullvadvpn.model.TunnelState.Disconnected Java object",
);
env.auto_local(object)
}
Self::Connecting { endpoint, location } => {
let constructor_signature = format!(
"({}{})V",
endpoint.jni_signature(),
location.jni_signature()
);

let endpoint_java = endpoint.into_java(env);
let location_java = location.into_java(env);
let parameters = [
jnix::AsJValue::as_jvalue(&endpoint_java),
jnix::AsJValue::as_jvalue(&location_java),
];

let class = env.get_class("net/mullvad/mullvadvpn/model/TunnelState$Connecting");

let object = env
.new_object(&class, constructor_signature, &parameters)
.expect(
"Failed to convert TunnelState::Connecting Rust type into net.mullvad.mullvadvpn.model.TunnelState.Connecting Java object",
);
env.auto_local(object)
}
Self::Connected { endpoint, location } => {
let constructor_signature = format!(
"({}{})V",
endpoint.jni_signature(),
location.jni_signature()
);

let endpoint_java = endpoint.into_java(env);
let location_java = location.into_java(env);
let parameters = [
jnix::AsJValue::as_jvalue(&endpoint_java),
jnix::AsJValue::as_jvalue(&location_java),
];

let class = env.get_class("net/mullvad/mullvadvpn/model/TunnelState$Connected");

let object = env
.new_object(&class, constructor_signature, &parameters)
.expect(
"Failed to convert TunnelState::Connected Rust type into net.mullvad.mullvadvpn.model.TunnelState.Connected Java object",
);
env.auto_local(object)
}
Self::Disconnecting(action_after_disconnect) => {
let constructor_signature =
format!("({})V", action_after_disconnect.jni_signature());

let action_after_disconnect_java = action_after_disconnect.into_java(env);
let parameters = [jnix::AsJValue::as_jvalue(&action_after_disconnect_java)];

let class = env.get_class("net/mullvad/mullvadvpn/model/TunnelState$Disconnecting");

let object = env
.new_object(&class, constructor_signature, &parameters)
.expect(
"Failed to convert TunnelState::Disconnecting Rust type into net.mullvad.mullvadvpn.model.TunnelState.Disconnecting Java object",
);
env.auto_local(object)
}
Self::Error(error_state) => {
let constructor_signature = format!("({})V", error_state.jni_signature());

let error_state_java = error_state.into_java(env);
let parameters = [jnix::AsJValue::as_jvalue(&error_state_java)];

let class = env.get_class("net/mullvad/mullvadvpn/model/TunnelState$Error");

let object = env
.new_object(&class, constructor_signature, &parameters)
.expect(
"Failed to convert TunnelState::Error Rust type into net.mullvad.mullvadvpn.model.TunnelState.Error Java object",
);
env.auto_local(object)
}
}
}
}

0 comments on commit 3b042e8

Please sign in to comment.