我正在尝试将一个Java的HashMap转换成Rust中的内部对象,并匹配数据类型。在Java中,HashMap是一个
我很难确定
正如您所见,我还没有做出太多进展,但首先,我想返回一个
HashMap<String, Object>
,其中Object
可以是任何数据类型,包括另一个HashMap<String,Object>
。我很难确定
JObject
是什么类型的对象,并且不知道如何将JObject
转换为像JString
这样的东西。正如您所见,我还没有做出太多进展,但首先,我想返回一个
String
、Integer
或Date
的字符串值(其中Date
将是Date.getTime()
的字符串值)。static DATE_CLASS: &str = "java/util/Date";
static INTEGER_CLASS: &str = "java/lang/Integer";
static STRING_CLASS: &str = "java/lang/String";
fn get_string_value(env: &JNIEnv, obj: JObject) -> String {
let ret = String::new();
if env.is_instance_of(obj, STRING_CLASS).unwrap() {
let ret2 = env.call_method(obj, "toString", "()Ljava/lang/String;", &[]).unwrap();
// Got a JValue- now what?
}
if env.is_instance_of(obj, INTEGER_CLASS).unwrap() {
let ret2 = env.call_method(obj, "toString", "()Ljava/lang/String;", &[]).unwrap();
// Got a JValue- now what?
}
if env.is_instance_of(obj, INTEGER_CLASS).unwrap() {
let ret2 = env.call_method(obj, "getTime", "()Ljava/lang/String;", &[]).unwrap();
// Got a JValue- now what?
}
ret
}
我认为我应该这样做(如果不是,请纠正我),首先检查JObject
是这些类的任何一个实例,根据它们的完全限定路径。一旦我知道它们是什么类型,就可以使用env.call_method
在它们上调用方法。结果是一个JValue
,它可以返回一些基本类型。
我假设除非我期望返回另一个对象,否则我应该使用这些方法,否则我会使用-
let message_ref = env.auto_local(ret2).as_obj();
如果需要,我可以调用另一个方法。但据我所知,如果需要将其转换为JString,则无法执行此操作。然而,这也是我目前知道如何从JString获取rust字符串的唯一方法,使用以下代码:
let s: String = env.get_string(a_j_string).expect("Couldn't get java string").into();
我这样做对吗?
如何将 JValue 转换为字符串?
我是否正确地应该使用 auto_local
将 JValue
转换为 JObject
,这样就可以再次调用它的方法了?
如果我应该使用原始类型 jchar
来获取 toString
的值——那么如何将其转换为 &str
或 String
?
编辑:
在 @Chris Jester-Young 的帮助下,我成功编写了 jobj_to_string
和 jobj_to_int
函数。
static INTEGER_CLASS: &str = "java/lang/Integer";
static STRING_CLASS: &str = "java/lang/String";
fn get_liquid_value(env: &JNIEnv, obj: JObject) -> LiquidValue {
let mut value = LiquidValue::Nil;
if env.is_instance_of(obj, STRING_CLASS).unwrap() {
match jobj_to_string(env, obj) {
Some(str) => {
value = LiquidValue::Scalar(LiquidScalar::from(str));
},
None => {}
}
}
if env.is_instance_of(obj, INTEGER_CLASS).unwrap() {
match jobj_to_i32(env, obj) {
Some(int) => {
value = LiquidValue::Scalar(LiquidScalar::from(int));
},
None => {}
}
}
value
}
fn jobj_to_string(env: &JNIEnv, obj: JObject) -> Option<String> {
let mut result = Option::None;
match env.call_method(obj, "toString", "()Ljava/lang/String;", &[]) {
Result::Ok(jvalue) => {
match jvalue.l() {
Result::Ok(jobject) => {
let string = String::from(env.get_string(jobject.into()).unwrap().to_str().unwrap());
result = Option::Some(string);
},
_ => {}
}
},
_ => {}
};
result
}
fn jobj_to_i32(env: &JNIEnv, obj: JObject) -> Option<i32> {
let mut result = Option::None;
match env.call_method(obj, "intValue", "()I", &[]) {
Ok(jvalue) => {
match jvalue.i() {
Ok(int) => {
result = Option::Some(int.to_owned());
},
_ => {}
}
},
_ => {}
}
result
}