1use crate::{exception::JavaCatchINI, j2r::IntoRustType, r2j::IntoJavaType};
2use std::borrow::BorrowMut;
3
4#[repr(transparent)]
6#[derive(Default, Debug)]
7pub struct JByte(pub i8);
8#[repr(transparent)]
9#[derive(Default, Debug)]
10pub struct JShort(pub i16);
11#[repr(transparent)]
12#[derive(Default, Debug)]
13pub struct JInt(pub i32);
14#[repr(transparent)]
15#[derive(Default, Debug)]
16pub struct JLong(pub i64);
17#[repr(transparent)]
18#[derive(Default, Debug)]
19pub struct JFloat(pub f32);
20#[repr(transparent)]
21#[derive(Default, Debug)]
22pub struct JDouble(pub f64);
23#[repr(transparent)]
24#[derive(Default, Debug)]
25pub struct JBoolean(pub bool);
26#[repr(transparent)]
27#[derive(Default, Debug)]
28pub struct JChar(pub char);
29
30#[repr(transparent)]
31#[derive(Default, Debug)]
32pub struct JVoid();
33
34pub trait JObjectGetters<'l> {
36 fn call_getter<T>(&self, name: &str, env: &mut jni::JNIEnv<'l>) -> crate::JResult<T>
37 where
38 T: JTypeInfo<'l>,
39 JValueGen<jni::objects::JObject<'l>>: crate::j2r::IntoRustType<'l, T>;
40}
41
42impl<'local> JObjectGetters<'local> for jni::objects::JObject<'local> {
43 fn call_getter<T>(&self, name: &str, env: &mut jni::JNIEnv<'local>) -> crate::JResult<T>
44 where
45 T: JTypeInfo<'local>,
46 JValueGen<jni::objects::JObject<'local>>: crate::j2r::IntoRustType<'local, T>,
47 {
48 let ty = T::j_type().to_string();
49 let e = env
50 .call_method(self, name, format!("(){ty}"), &[])
51 .j_catch_ini(env, &format!("Call Java getter: {name}()"))?;
52
53 e.into_rust(env)
54 }
55}
56
57use jni::objects::{JValueGen, JValueOwned};
58
59pub use jtypes::*;
60mod jtypes {
61 use crate::prelude::*;
62 use jni::{
64 objects::{JObject, JValueOwned},
65 signature::{JavaType, ReturnType},
66 };
67
68 #[doc(hidden)]
70 pub struct TypeSignatureBuilder {
71 args: Vec<jni::signature::JavaType>,
72 }
73
74 #[allow(dead_code)]
75 impl<'l> TypeSignatureBuilder {
76 pub fn new1<V: JTypeInfo<'l>>(_: &V) -> Self {
77 Self {
78 args: vec![V::j_type()],
79 }
80 }
81
82 pub fn new_noargs1<R: JTypeInfo<'l>>(_: &R) -> jni::signature::TypeSignature {
83 jni::signature::TypeSignature {
84 args: vec![],
85 ret: R::j_return_type(),
86 }
87 }
88
89 pub fn arg1<V: JTypeInfo<'l>>(mut self, _: &V) -> Self {
90 self.args.push(V::j_type());
91 self
92 }
93
94 pub fn ret1<R: JTypeInfo<'l>>(self, _: &R) -> jni::signature::TypeSignature {
95 jni::signature::TypeSignature {
96 args: self.args,
97 ret: R::j_return_type(),
98 }
99 }
100
101 pub fn new<V: JTypeInfo<'l>>() -> Self {
102 Self {
103 args: vec![V::j_type()],
104 }
105 }
106
107 pub fn new_noargs<R: JTypeInfo<'l>>() -> jni::signature::TypeSignature {
108 jni::signature::TypeSignature {
109 args: vec![],
110 ret: R::j_return_type(),
111 }
112 }
113
114 pub fn arg<V: JTypeInfo<'l>>(mut self) -> Self {
115 self.args.push(V::j_type());
116 self
117 }
118
119 pub fn ret<R: JTypeInfo<'l>>(self) -> jni::signature::TypeSignature {
120 jni::signature::TypeSignature {
121 args: self.args,
122 ret: R::j_return_type(),
123 }
124 }
125 }
126
127 #[doc(hidden)]
128 pub fn arg1<V: for<'l> JTypeInfo<'l>>(v: &V) -> TypeSignatureBuilder {
129 TypeSignatureBuilder::new1(v)
130 }
131
132 pub fn arg<V: for<'l> JTypeInfo<'l>>() -> TypeSignatureBuilder {
133 TypeSignatureBuilder::new::<V>()
134 }
135
136 #[macro_export]
137 macro_rules! signature_by_type {
138 ($a1:ty , $($arg:ty),* => $_return:ty) => {
139 TypeSignatureBuilder::new::<$a1>()
140 $(.arg::<$arg>())
141 *
142 .ret::<$_return>()
143 };
144 ( => $_return:ty) => { TypeSignatureBuilder::new_noargs::<$_return>() };
145 ( $a1:ty => $_return:ty) => { TypeSignatureBuilder::new::<$a1>().ret::<$_return>() };
146
147 ( => ) => { signature_by_type! {=> JVoid} };
148 ( $a1:ty => ) => { signature_by_type!($a1 => JVoid) };
149 ($a1:ty , $($arg:ty),* => ) => { signature_by_type!( $a1 , $($arg)* => JVoid) };
150 }
151
152 #[macro_export]
153 macro_rules! signature_by_value {
154 ($a1:expr , $($arg:expr),* => $_return:expr) => {
155 TypeSignatureBuilder::new1(&$a1)
156 $(.arg1(&$arg))
157 *
158 .ret1(&$_return)
159 };
160 ( => $_return:expr) => { TypeSignatureBuilder::new_noargs1(&$_return) };
161 ( $a1:expr => $_return:expr) => { TypeSignatureBuilder::new1(&$a1).ret1(&$_return) };
162
163 ( => ) => { signature_by_value! { => JVoid() } };
164 ( $a1:expr => ) => { signature_by_value!( $a1 => JVoid()) };
165 ($a1:expr , $($arg:expr),* => ) => { signature_by_value!( $a1 , $($arg)* => JVoid()) };
166 }
167
168 pub trait JTypeInfo<'local>
170 where
171 Self: Sized,
172 {
173 fn j_return_type() -> jni::signature::ReturnType;
174 fn j_type() -> jni::signature::JavaType;
175 fn j_value_type(&self) -> jni::signature::JavaType {
176 Self::j_type()
177 }
178 fn into_j_value(self, _: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>>;
179 }
180
181 impl<'local, T: JTypeInfo<'local> + Default> JTypeInfo<'local> for Option<T> {
182 fn j_return_type() -> ReturnType {
183 T::j_return_type()
184 }
185
186 fn j_type() -> JavaType {
187 T::j_type()
188 }
189
190 fn into_j_value(self, env: &mut JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
191 match self {
192 None => {
193 match T::j_type() {
194 JavaType::Primitive(_) => T::default().into_j_value(env),
195 _ => Ok(JValueOwned::Object(JObject::null()))
196 }
197 }
198 Some(v) => v.into_j_value(env)
199 }
200 }
201 }
202
203 impl<'local> JTypeInfo<'local> for JVoid {
204 fn j_return_type() -> jni::signature::ReturnType {
205 ReturnType::Primitive(jni::signature::Primitive::Void)
206 }
207
208 fn j_type() -> jni::signature::JavaType {
209 JavaType::Primitive(jni::signature::Primitive::Void)
210 }
211
212 fn into_j_value(self, _: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
213 Ok(JValueOwned::Void)
214 }
215 }
216
217 impl<'local> JTypeInfo<'local> for u8 {
218 fn j_return_type() -> jni::signature::ReturnType {
219 ReturnType::Primitive(jni::signature::Primitive::Byte)
220 }
221
222 fn j_type() -> jni::signature::JavaType {
223 JavaType::Primitive(jni::signature::Primitive::Byte)
224 }
225
226 fn into_j_value(self, _: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
227 Ok(JValueOwned::Byte(self as i8))
228 }
229 }
230
231 impl<'local> JTypeInfo<'local> for i16 {
232 fn j_return_type() -> jni::signature::ReturnType {
233 ReturnType::Primitive(jni::signature::Primitive::Short)
234 }
235
236 fn j_type() -> jni::signature::JavaType {
237 JavaType::Primitive(jni::signature::Primitive::Short)
238 }
239
240 fn into_j_value(self, _: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
241 Ok(JValueOwned::Short(self))
242 }
243 }
244
245 impl<'local> JTypeInfo<'local> for i32 {
246 fn j_return_type() -> jni::signature::ReturnType {
247 ReturnType::Primitive(jni::signature::Primitive::Int)
248 }
249
250 fn j_type() -> jni::signature::JavaType {
251 JavaType::Primitive(jni::signature::Primitive::Int)
252 }
253
254 fn into_j_value(self, _: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
255 Ok(JValueOwned::Int(self))
256 }
257 }
258
259 impl<'local> JTypeInfo<'local> for i64 {
260 fn j_return_type() -> jni::signature::ReturnType {
261 ReturnType::Primitive(jni::signature::Primitive::Long)
262 }
263
264 fn j_type() -> jni::signature::JavaType {
265 JavaType::Primitive(jni::signature::Primitive::Long)
266 }
267
268 fn into_j_value(self, _: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
269 Ok(JValueOwned::Long(self))
270 }
271 }
272
273 impl<'local> JTypeInfo<'local> for f32 {
274 fn j_return_type() -> jni::signature::ReturnType {
275 ReturnType::Primitive(jni::signature::Primitive::Float)
276 }
277
278 fn j_type() -> jni::signature::JavaType {
279 JavaType::Primitive(jni::signature::Primitive::Float)
280 }
281
282 fn into_j_value(self, _: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
283 Ok(JValueOwned::Float(self))
284 }
285 }
286
287 impl<'local> JTypeInfo<'local> for f64 {
288 fn j_return_type() -> jni::signature::ReturnType {
289 ReturnType::Primitive(jni::signature::Primitive::Double)
290 }
291
292 fn j_type() -> jni::signature::JavaType {
293 JavaType::Primitive(jni::signature::Primitive::Double)
294 }
295
296 fn into_j_value(self, _: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
297 Ok(JValueOwned::Double(self))
298 }
299 }
300
301 impl<'local> JTypeInfo<'local> for bool {
302 fn j_return_type() -> jni::signature::ReturnType {
303 ReturnType::Primitive(jni::signature::Primitive::Boolean)
304 }
305
306 fn j_type() -> jni::signature::JavaType {
307 JavaType::Primitive(jni::signature::Primitive::Boolean)
308 }
309
310 fn into_j_value(self, _: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
311 Ok(JValueOwned::Bool(self as u8))
312 }
313 }
314
315 impl<'local> JTypeInfo<'local> for char {
316 fn j_return_type() -> jni::signature::ReturnType {
317 ReturnType::Primitive(jni::signature::Primitive::Char)
318 }
319
320 fn j_type() -> jni::signature::JavaType {
321 JavaType::Primitive(jni::signature::Primitive::Char)
322 }
323
324 fn into_j_value(self, _: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
325 Ok(JValueOwned::Char(self as u16))
326 }
327 }
328
329 impl<'local> JTypeInfo<'local> for JByte {
332 fn j_return_type() -> jni::signature::ReturnType {
333 ReturnType::Object
334 }
335
336 fn j_type() -> jni::signature::JavaType {
337 JavaType::Object("java/lang/Byte".to_string())
338 }
339
340 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
341 let obj = self.into_java(env)?;
342 Ok(JValueOwned::Object(obj))
343 }
344 }
345
346 impl<'local> JTypeInfo<'local> for JShort {
347 fn j_return_type() -> jni::signature::ReturnType {
348 ReturnType::Object
349 }
350
351 fn j_type() -> jni::signature::JavaType {
352 JavaType::Object("java/lang/Short".to_string())
353 }
354
355 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
356 let obj = self.into_java(env)?;
357 Ok(JValueOwned::Object(obj))
358 }
359 }
360
361 impl<'local> JTypeInfo<'local> for JInt {
362 fn j_return_type() -> jni::signature::ReturnType {
363 ReturnType::Object
364 }
365
366 fn j_type() -> jni::signature::JavaType {
367 JavaType::Object("java/lang/Integer".to_string())
368 }
369
370 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
371 let obj = self.into_java(env)?;
372 Ok(JValueOwned::Object(obj))
373 }
374 }
375
376 impl<'local> JTypeInfo<'local> for JLong {
377 fn j_return_type() -> jni::signature::ReturnType {
378 ReturnType::Object
379 }
380
381 fn j_type() -> jni::signature::JavaType {
382 JavaType::Object("java/lang/Long".to_string())
383 }
384
385 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
386 let obj = self.0.into_java(env)?;
387 Ok(JValueOwned::Object(obj))
388 }
389 }
390
391 impl<'local> JTypeInfo<'local> for JFloat {
392 fn j_return_type() -> jni::signature::ReturnType {
393 ReturnType::Object
394 }
395
396 fn j_type() -> jni::signature::JavaType {
397 JavaType::Object("java/lang/Float".to_string())
398 }
399
400 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
401 let obj = self.into_java(env)?;
402 Ok(JValueOwned::Object(obj))
403 }
404 }
405
406 impl<'local> JTypeInfo<'local> for JDouble {
407 fn j_return_type() -> jni::signature::ReturnType {
408 ReturnType::Object
409 }
410
411 fn j_type() -> jni::signature::JavaType {
412 JavaType::Object("java/lang/Double".to_string())
413 }
414
415 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
416 let obj = self.into_java(env)?;
417 Ok(JValueOwned::Object(obj))
418 }
419 }
420
421 impl<'local> JTypeInfo<'local> for JBoolean {
422 fn j_return_type() -> jni::signature::ReturnType {
423 ReturnType::Object
424 }
425
426 fn j_type() -> jni::signature::JavaType {
427 JavaType::Object("java/lang/Boolean".to_string())
428 }
429
430 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
431 let obj = self.into_java(env)?;
432 Ok(JValueOwned::Object(obj))
433 }
434 }
435
436 impl<'local> JTypeInfo<'local> for JChar {
437 fn j_return_type() -> jni::signature::ReturnType {
438 ReturnType::Object
439 }
440
441 fn j_type() -> jni::signature::JavaType {
442 JavaType::Object("java/lang/Character".to_string())
443 }
444
445 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
446 let obj = self.into_java(env)?;
447 Ok(JValueOwned::Object(obj))
448 }
449 }
450
451 impl<'local> JTypeInfo<'local> for String {
454 fn j_return_type() -> jni::signature::ReturnType {
455 ReturnType::Object
456 }
457
458 fn j_type() -> jni::signature::JavaType {
459 JavaType::Object("java/lang/String".to_string())
460 }
461
462 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
463 let obj = env
464 .new_string(&self)
465 .j_catch_ini(env, "String -> JString")?;
466 Ok(JValueOwned::Object(JObject::from(obj)))
467 }
468 }
469
470 impl<'local> JTypeInfo<'local> for Vec<u8> {
471 fn j_return_type() -> jni::signature::ReturnType {
472 ReturnType::Object
473 }
474
475 fn j_type() -> jni::signature::JavaType {
476 JavaType::Array(Box::new(JavaType::Primitive(
477 jni::signature::Primitive::Byte,
478 )))
479 }
480
481 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> JResult<JValueOwned<'local>> {
482 let array = env
483 .byte_array_from_slice(&self)
484 .j_catch_ini(env, "Vec<u8> -> JByteArray")?;
485 Ok(JValueOwned::Object(JObject::from(array)))
486 }
487 }
488
489 #[cfg(test)]
490 pub mod tests {
491 use jni::signature::{Primitive, TypeSignature};
492
493 use super::*;
494
495 #[test]
496 pub fn test_primitive_types() {
497 assert_eq!(100u8.j_value_type(), JavaType::Primitive(Primitive::Byte));
498
499 assert_eq!(100i16.j_value_type(), JavaType::Primitive(Primitive::Short));
500
501 assert_eq!(100i32.j_value_type(), JavaType::Primitive(Primitive::Int));
502
503 assert_eq!(100i64.j_value_type(), JavaType::Primitive(Primitive::Long));
504
505 assert_eq!(
506 100.0f32.j_value_type(),
507 JavaType::Primitive(Primitive::Float)
508 );
509
510 assert_eq!(
511 100.0f64.j_value_type(),
512 JavaType::Primitive(Primitive::Double)
513 );
514
515 assert_eq!(true.j_value_type(), JavaType::Primitive(Primitive::Boolean));
516
517 assert_eq!('a'.j_value_type(), JavaType::Primitive(Primitive::Char));
518 }
519
520 #[test]
521 pub fn test_wrapper_types() {
522 assert_eq!(
523 JByte(100).j_value_type(),
524 JavaType::Object("java/lang/Byte".to_string())
525 );
526
527 assert_eq!(
528 JShort(100).j_value_type(),
529 JavaType::Object("java/lang/Short".to_string())
530 );
531
532 assert_eq!(
533 JInt(100).j_value_type(),
534 JavaType::Object("java/lang/Integer".to_string())
535 );
536
537 assert_eq!(
538 JLong(100).j_value_type(),
539 JavaType::Object("java/lang/Long".to_string())
540 );
541
542 assert_eq!(
543 JFloat(100.0).j_value_type(),
544 JavaType::Object("java/lang/Float".to_string())
545 );
546
547 assert_eq!(
548 JDouble(100.0).j_value_type(),
549 JavaType::Object("java/lang/Double".to_string())
550 );
551
552 assert_eq!(
553 JBoolean(true).j_value_type(),
554 JavaType::Object("java/lang/Boolean".to_string())
555 );
556
557 assert_eq!(
558 JChar('a').j_value_type(),
559 JavaType::Object("java/lang/Character".to_string())
560 );
561 }
562
563 #[test]
564 pub fn test_class_types() {
565 assert_eq!(
566 "string".to_string().j_value_type(),
567 JavaType::Object("java/lang/String".to_string())
568 );
569 }
570
571 #[test]
572 pub fn test_signature_builder() {
573 assert_eq!(
575 TypeSignature::from_str("(ILjava/lang/String;)F").unwrap(),
576 arg::<i32>().arg::<String>().ret::<f32>()
577 );
578
579 assert_eq!(
580 TypeSignature::from_str("(ILjava/lang/String;)F").unwrap(),
581 arg1(&10).arg1(&"test".to_string()).ret1(&10_f32)
582 );
583 }
584
585 #[test]
586 pub fn test_signature_macro_by_type() {
587 assert_eq!(
588 TypeSignature::from_str("(Ljava/lang/String;I)V").unwrap(),
589 signature_by_type!( String , i32 => )
590 );
591 assert_eq!(
592 TypeSignature::from_str("(Ljava/lang/String;[B)V").unwrap(),
593 signature_by_type!( String , Vec<u8> => JVoid )
594 );
595 assert_eq!(
596 TypeSignature::from_str("(Ljava/lang/String;[B)I").unwrap(),
597 signature_by_type!( Option<String> , Option<Vec<u8>> => Option<i32> )
598 );
599
600 println!("{}", signature_by_type!( => ));
601 println!("{}", signature_by_type!( => String));
602 println!("{}", signature_by_type!( => i32));
603 println!("{}", signature_by_type!( String => i32));
604 println!("{}", signature_by_type!( String => ));
605 println!("{}", signature_by_type!( String , i32 => i32));
606 println!("{}", signature_by_type!( String , i32 => i32));
607 println!("{}", signature_by_type!( String , i32 => ));
608 println!("{}", signature_by_type!( String , Vec<u8> => JVoid ));
609 }
610
611 #[test]
612 pub fn test_signature_macro_by_value() {
613 let string = "ok".to_string();
614 assert_eq!(
615 TypeSignature::from_str("(Ljava/lang/String;I)I").unwrap(),
616 signature_by_value!( string, 10_i32 => 10_i32)
617 );
618
619 println!("{}", signature_by_value!( => ));
620 println!("{}", signature_by_value!( => string));
621 println!("{}", signature_by_value!( => 10_i32));
622 println!("{}", signature_by_value!( string => 10_i32));
623 println!("{}", signature_by_value!( string => ));
624 println!("{}", signature_by_value!( string , 10_i32 => 10_i32));
625 println!("{}", signature_by_value!( string , 10_i32 => 10_i32));
626 println!("{}", signature_by_value!( string , 10_i32 => ));
627 }
628 }
629}
630
631#[derive(Default)]
634pub struct JList<T>(pub Vec<T>);
635
636impl<T> JList<T> {
637 pub fn add(&mut self, element: T) {
638 self.0.push(element)
639 }
640
641 pub fn add_at(&mut self, index: usize, element: T) {
642 self.0.insert(index, element)
643 }
644
645 pub fn get(&self, index: usize) -> Option<&T> {
646 self.0.get(index)
647 }
648}
649
650impl<'local, T> JList<T>
651where
652 jni::objects::JObject<'local>: IntoRustType<'local, i32> + IntoRustType<'local, T>,
653{
654 fn from_j_object(
655 mut obj: jni::objects::JObject<'local>,
656 env: &mut jni::JNIEnv<'local>,
657 ) -> crate::JResult<Self> {
658 let mut items = vec![];
659
660 let size: i32 = obj.borrow_mut().call_getter("size", env)?;
661 for i in 0..size {
662 let index = i.into_j_value(env)?;
663 let e = env
664 .call_method(
665 &mut obj,
666 "get",
667 "(I)Ljava/lang/Object;".to_string(),
668 &[index.borrow()],
669 )
670 .j_catch_ini(env, &"List.get(int) failed".to_string())?;
671
672 let obj = e.l()?;
673 let item: T = obj.into_rust(env)?;
674 items.push(item)
675 }
676
677 Ok(JList(items))
678 }
679}
680
681impl<'local, T> JList<T>
682where
683 T: IntoJavaType<'local, jni::objects::JObject<'local>>,
684{
685 fn into_j_object(
686 self,
687 env: &mut jni::JNIEnv<'local>,
688 ) -> crate::JResult<jni::objects::JObject<'local>> {
689 let class = env
690 .find_class("java/util/ArrayList")
691 .j_catch_ini(env, "ArrayList class not found")?;
692 let mut array_list = env
693 .new_object(class, "()V", &[])
694 .j_catch_ini(env, "Failed to create ArrayList")?;
695
696 for item in self.0.into_iter() {
697 let obj = item.into_java(env)?;
698 let index = JValueOwned::Object(obj);
699 env.call_method(
700 &mut array_list,
701 "add",
702 "(Ljava/lang/Object;)Z".to_string(),
703 &[index.borrow()],
704 )
705 .j_catch_ini(env, &"ArrayList.add(T) failed".to_string())?;
706 }
707
708 Ok(array_list)
709 }
710}
711
712impl<'local, T> IntoRustType<'local, JList<T>> for jni::objects::JObject<'local>
713where
714 jni::objects::JObject<'local>: IntoRustType<'local, i32> + IntoRustType<'local, T>,
715{
716 fn into_rust(self, env: &mut jni::JNIEnv<'local>) -> crate::JResult<JList<T>> {
717 JList::from_j_object(self, env)
718 }
719}
720
721impl<'local, T> IntoJavaType<'local, jni::objects::JObject<'local>> for JList<T>
722where
723 T: IntoJavaType<'local, jni::objects::JObject<'local>>,
724{
725 fn into_java(
726 self,
727 env: &mut jni::JNIEnv<'local>,
728 ) -> crate::JResult<jni::objects::JObject<'local>> {
729 self.into_j_object(env)
730 }
731}
732
733impl<'local, T> IntoRustType<'local, JList<T>>
734for jni::objects::JValueGen<jni::objects::JObject<'local>>
735where
736 jni::objects::JObject<'local>: IntoRustType<'local, i32> + IntoRustType<'local, T>,
737{
738 fn into_rust(self, env: &mut jni::JNIEnv<'local>) -> crate::JResult<JList<T>> {
739 let obj = self.l()?;
740 JList::from_j_object(obj, env)
741 }
742}
743
744impl<'local, T> JTypeInfo<'local> for JList<T>
745where
746 T: IntoJavaType<'local, jni::objects::JObject<'local>>,
747{
748 fn j_return_type() -> jni::signature::ReturnType {
749 jni::signature::ReturnType::Object
750 }
751
752 fn j_type() -> jni::signature::JavaType {
753 jni::signature::JavaType::Object("java/util/List".to_string())
754 }
755
756 fn into_j_value(self, env: &mut jni::JNIEnv<'local>) -> crate::JResult<JValueOwned<'local>> {
757 let obj = self.into_j_object(env)?;
758 Ok(JValueOwned::Object(jni::objects::JObject::from(obj)))
759 }
760}