rust_jni/jni/
primitives.rs

1use jni::class::*;
2use jni::*;
3use jni_sys;
4use std::char;
5use std::iter;
6use std::ptr;
7
8include!("call_jni_method.rs");
9
10/// A macro for generating [`JniType`](trait.JniType.html) implementation for primitive types.
11macro_rules! jni_type_trait {
12    ($type:ty, $default:expr, $method:ident, $static_method:ident) => {
13        impl JniType for $type {
14            fn default() -> Self {
15                $default
16            }
17
18            unsafe fn call_method<In: ToJniTuple>(
19                object: &Object,
20                method_id: jni_sys::jmethodID,
21                arguments: In,
22            ) -> Self {
23                In::$method(object, method_id, arguments)
24            }
25
26            unsafe fn call_static_method<In: ToJniTuple>(
27                class: &Class,
28                method_id: jni_sys::jmethodID,
29                arguments: In,
30            ) -> Self {
31                In::$static_method(class, method_id, arguments)
32            }
33        }
34    };
35}
36
37jni_type_trait!(
38    jni_sys::jobject,
39    ptr::null_mut(),
40    call_object_method,
41    call_static_object_method
42);
43jni_type_trait!((), (), call_void_method, call_static_void_method);
44jni_type_trait!(
45    jni_sys::jboolean,
46    jni_sys::JNI_FALSE,
47    call_boolean_method,
48    call_static_boolean_method
49);
50jni_type_trait!(jni_sys::jchar, 0, call_char_method, call_static_char_method);
51jni_type_trait!(jni_sys::jbyte, 0, call_byte_method, call_static_byte_method);
52jni_type_trait!(
53    jni_sys::jshort,
54    0,
55    call_short_method,
56    call_static_short_method
57);
58jni_type_trait!(jni_sys::jint, 0, call_int_method, call_static_int_method);
59jni_type_trait!(jni_sys::jlong, 0, call_long_method, call_static_long_method);
60jni_type_trait!(
61    jni_sys::jfloat,
62    0.,
63    call_float_method,
64    call_static_float_method
65);
66jni_type_trait!(
67    jni_sys::jdouble,
68    0.,
69    call_double_method,
70    call_static_double_method
71);
72
73macro_rules! generate_jni_type_tests {
74    (
75        $module:ident,
76        $jni_type:ty,
77        $default:expr,
78        $result:expr,
79        $jni_method:ident,
80        $jni_static_method:ident
81    ) => {
82        #[cfg(test)]
83        mod $module {
84            use super::*;
85            use jni::testing::*;
86            use std::mem;
87
88            #[test]
89            fn default() {
90                assert_eq!(<$jni_type as JniType>::default(), $default);
91            }
92
93            #[test]
94            fn call_method() {
95                static mut METHOD_CALLS: i32 = 0;
96                static mut METHOD_ENV_ARGUMENT: *mut jni_sys::JNIEnv = ptr::null_mut();
97                static mut METHOD_OBJECT_ARGUMENT: jni_sys::jobject = ptr::null_mut();
98                static mut METHOD_METHOD_ARGUMENT: jni_sys::jmethodID = ptr::null_mut();
99                static mut METHOD_ARGUMENT0: jni_sys::jint = 0;
100                static mut METHOD_ARGUMENT1: jni_sys::jdouble = 0.;
101                static mut METHOD_RESULT: $jni_type = $default;
102                type VariadicFn = unsafe extern "C" fn(
103                    env: *mut jni_sys::JNIEnv,
104                    object: jni_sys::jobject,
105                    method_id: jni_sys::jmethodID,
106                    ...
107                ) -> $jni_type;
108                type TestFn = unsafe extern "C" fn(
109                    env: *mut jni_sys::JNIEnv,
110                    object: jni_sys::jobject,
111                    method_id: jni_sys::jmethodID,
112                    argument0: jni_sys::jint,
113                    argument1: jni_sys::jdouble,
114                ) -> $jni_type;
115                unsafe extern "C" fn method(
116                    env: *mut jni_sys::JNIEnv,
117                    object: jni_sys::jobject,
118                    method_id: jni_sys::jmethodID,
119                    argument0: jni_sys::jint,
120                    argument1: jni_sys::jdouble,
121                ) -> $jni_type {
122                    METHOD_CALLS += 1;
123                    METHOD_ENV_ARGUMENT = env;
124                    METHOD_OBJECT_ARGUMENT = object;
125                    METHOD_METHOD_ARGUMENT = method_id;
126                    METHOD_ARGUMENT0 = argument0;
127                    METHOD_ARGUMENT1 = argument1;
128                    METHOD_RESULT
129                }
130                let vm = test_vm(ptr::null_mut());
131                let raw_jni_env = jni_sys::JNINativeInterface_ {
132                    $jni_method: Some(unsafe { mem::transmute::<TestFn, VariadicFn>(method) }),
133                    ..empty_raw_jni_env()
134                };
135                let raw_jni_env = &mut (&raw_jni_env as jni_sys::JNIEnv) as *mut jni_sys::JNIEnv;
136                let env = test_env(&vm, raw_jni_env);
137                let raw_object = 0x91011 as jni_sys::jobject;
138                let object = test_object(&env, raw_object);
139                let method_id = 0x7654 as jni_sys::jmethodID;
140                let arguments = (17 as i32, 19. as f64);
141                let result = $result;
142                unsafe {
143                    METHOD_RESULT = result;
144                    assert_eq!(
145                        <$jni_type>::call_method(&object, method_id, arguments),
146                        result
147                    );
148                    assert_eq!(METHOD_CALLS, 1);
149                    assert_eq!(METHOD_ENV_ARGUMENT, raw_jni_env);
150                    assert_eq!(METHOD_OBJECT_ARGUMENT, raw_object);
151                    assert_eq!(METHOD_METHOD_ARGUMENT, method_id);
152                    assert_eq!(METHOD_ARGUMENT0, arguments.0);
153                    assert_eq!(METHOD_ARGUMENT1, arguments.1);
154                }
155            }
156
157            #[test]
158            fn call_static_method() {
159                static mut METHOD_CALLS: i32 = 0;
160                static mut METHOD_ENV_ARGUMENT: *mut jni_sys::JNIEnv = ptr::null_mut();
161                static mut METHOD_OBJECT_ARGUMENT: jni_sys::jobject = ptr::null_mut();
162                static mut METHOD_METHOD_ARGUMENT: jni_sys::jmethodID = ptr::null_mut();
163                static mut METHOD_ARGUMENT0: jni_sys::jint = 0;
164                static mut METHOD_ARGUMENT1: jni_sys::jdouble = 0.;
165                static mut METHOD_RESULT: $jni_type = $default;
166                type VariadicFn = unsafe extern "C" fn(
167                    env: *mut jni_sys::JNIEnv,
168                    object: jni_sys::jobject,
169                    method_id: jni_sys::jmethodID,
170                    ...
171                ) -> $jni_type;
172                type TestFn = unsafe extern "C" fn(
173                    env: *mut jni_sys::JNIEnv,
174                    object: jni_sys::jobject,
175                    method_id: jni_sys::jmethodID,
176                    argument0: jni_sys::jint,
177                    argument1: jni_sys::jdouble,
178                ) -> $jni_type;
179                unsafe extern "C" fn method(
180                    env: *mut jni_sys::JNIEnv,
181                    object: jni_sys::jobject,
182                    method_id: jni_sys::jmethodID,
183                    argument0: jni_sys::jint,
184                    argument1: jni_sys::jdouble,
185                ) -> $jni_type {
186                    METHOD_CALLS += 1;
187                    METHOD_ENV_ARGUMENT = env;
188                    METHOD_OBJECT_ARGUMENT = object;
189                    METHOD_METHOD_ARGUMENT = method_id;
190                    METHOD_ARGUMENT0 = argument0;
191                    METHOD_ARGUMENT1 = argument1;
192                    METHOD_RESULT
193                }
194                let vm = test_vm(ptr::null_mut());
195                let raw_jni_env = jni_sys::JNINativeInterface_ {
196                    $jni_static_method: Some(unsafe {
197                        mem::transmute::<TestFn, VariadicFn>(method)
198                    }),
199                    ..empty_raw_jni_env()
200                };
201                let raw_jni_env = &mut (&raw_jni_env as jni_sys::JNIEnv) as *mut jni_sys::JNIEnv;
202                let env = test_env(&vm, raw_jni_env);
203                let raw_object = 0x91011 as jni_sys::jobject;
204                let class = test_class(&env, raw_object);
205                let method_id = 0x7654 as jni_sys::jmethodID;
206                let arguments = (17 as i32, 19. as f64);
207                let result = $result;
208                unsafe {
209                    METHOD_RESULT = result;
210                    assert_eq!(
211                        <$jni_type>::call_static_method(&class, method_id, arguments),
212                        result
213                    );
214                    assert_eq!(METHOD_CALLS, 1);
215                    assert_eq!(METHOD_ENV_ARGUMENT, raw_jni_env);
216                    assert_eq!(METHOD_OBJECT_ARGUMENT, raw_object);
217                    assert_eq!(METHOD_METHOD_ARGUMENT, method_id);
218                    assert_eq!(METHOD_ARGUMENT0, arguments.0);
219                    assert_eq!(METHOD_ARGUMENT1, arguments.1);
220                }
221            }
222        }
223    };
224}
225
226generate_jni_type_tests!(
227    jni_type_void_tests,
228    (),
229    (),
230    (),
231    CallVoidMethod,
232    CallStaticVoidMethod
233);
234
235generate_jni_type_tests!(
236    jni_type_boolean_tests,
237    jni_sys::jboolean,
238    jni_sys::JNI_FALSE,
239    jni_sys::JNI_TRUE,
240    CallBooleanMethod,
241    CallStaticBooleanMethod
242);
243
244generate_jni_type_tests!(
245    jni_type_char_tests,
246    jni_sys::jchar,
247    0,
248    42,
249    CallCharMethod,
250    CallStaticCharMethod
251);
252
253generate_jni_type_tests!(
254    jni_type_byte_tests,
255    jni_sys::jbyte,
256    0,
257    42,
258    CallByteMethod,
259    CallStaticByteMethod
260);
261
262generate_jni_type_tests!(
263    jni_type_short_tests,
264    jni_sys::jshort,
265    0,
266    42,
267    CallShortMethod,
268    CallStaticShortMethod
269);
270
271generate_jni_type_tests!(
272    jni_type_int_tests,
273    jni_sys::jint,
274    0,
275    42,
276    CallIntMethod,
277    CallStaticIntMethod
278);
279
280generate_jni_type_tests!(
281    jni_type_long_tests,
282    jni_sys::jlong,
283    0,
284    42,
285    CallLongMethod,
286    CallStaticLongMethod
287);
288
289generate_jni_type_tests!(
290    jni_type_float_tests,
291    jni_sys::jfloat,
292    0.,
293    42.,
294    CallFloatMethod,
295    CallStaticFloatMethod
296);
297
298generate_jni_type_tests!(
299    jni_type_double_tests,
300    jni_sys::jdouble,
301    0.,
302    42.,
303    CallDoubleMethod,
304    CallStaticDoubleMethod
305);
306
307/// A trait that implements calling JNI variadic functions using a macro to generate
308/// it's instances for tuples of different sizes.
309/// This is essentially the "[`JniType`](trait.JniType.html) for packed argument tuples".
310///
311/// THIS TRAIT SHOULD NOT BE USED MANUALLY.
312// TODO: reimplement once Rust has variadic functions or variadic templates.
313#[doc(hidden)]
314pub trait ToJniTuple {
315    unsafe fn call_constructor(
316        class: &Class,
317        method_id: jni_sys::jmethodID,
318        arguments: Self,
319    ) -> jni_sys::jobject;
320
321    unsafe fn call_object_method(
322        object: &Object,
323        method_id: jni_sys::jmethodID,
324        arguments: Self,
325    ) -> jni_sys::jobject;
326
327    unsafe fn call_static_object_method(
328        class: &Class,
329        method_id: jni_sys::jmethodID,
330        arguments: Self,
331    ) -> jni_sys::jobject;
332
333    unsafe fn call_void_method(
334        object: &Object,
335        method_id: jni_sys::jmethodID,
336        arguments: Self,
337    ) -> ();
338
339    unsafe fn call_static_void_method(
340        class: &Class,
341        method_id: jni_sys::jmethodID,
342        arguments: Self,
343    ) -> ();
344
345    unsafe fn call_boolean_method(
346        object: &Object,
347        method_id: jni_sys::jmethodID,
348        arguments: Self,
349    ) -> jni_sys::jboolean;
350
351    unsafe fn call_static_boolean_method(
352        class: &Class,
353        method_id: jni_sys::jmethodID,
354        arguments: Self,
355    ) -> jni_sys::jboolean;
356
357    unsafe fn call_char_method(
358        object: &Object,
359        method_id: jni_sys::jmethodID,
360        arguments: Self,
361    ) -> jni_sys::jchar;
362
363    unsafe fn call_static_char_method(
364        class: &Class,
365        method_id: jni_sys::jmethodID,
366        arguments: Self,
367    ) -> jni_sys::jchar;
368
369    unsafe fn call_byte_method(
370        object: &Object,
371        method_id: jni_sys::jmethodID,
372        arguments: Self,
373    ) -> jni_sys::jbyte;
374
375    unsafe fn call_static_byte_method(
376        class: &Class,
377        method_id: jni_sys::jmethodID,
378        arguments: Self,
379    ) -> jni_sys::jbyte;
380
381    unsafe fn call_short_method(
382        object: &Object,
383        method_id: jni_sys::jmethodID,
384        arguments: Self,
385    ) -> jni_sys::jshort;
386
387    unsafe fn call_static_short_method(
388        class: &Class,
389        method_id: jni_sys::jmethodID,
390        arguments: Self,
391    ) -> jni_sys::jshort;
392
393    unsafe fn call_int_method(
394        object: &Object,
395        method_id: jni_sys::jmethodID,
396        arguments: Self,
397    ) -> jni_sys::jint;
398
399    unsafe fn call_static_int_method(
400        class: &Class,
401        method_id: jni_sys::jmethodID,
402        arguments: Self,
403    ) -> jni_sys::jint;
404
405    unsafe fn call_long_method(
406        object: &Object,
407        method_id: jni_sys::jmethodID,
408        arguments: Self,
409    ) -> jni_sys::jlong;
410
411    unsafe fn call_static_long_method(
412        class: &Class,
413        method_id: jni_sys::jmethodID,
414        arguments: Self,
415    ) -> jni_sys::jlong;
416
417    unsafe fn call_float_method(
418        object: &Object,
419        method_id: jni_sys::jmethodID,
420        arguments: Self,
421    ) -> jni_sys::jfloat;
422
423    unsafe fn call_static_float_method(
424        class: &Class,
425        method_id: jni_sys::jmethodID,
426        arguments: Self,
427    ) -> jni_sys::jfloat;
428
429    unsafe fn call_double_method(
430        object: &Object,
431        method_id: jni_sys::jmethodID,
432        arguments: Self,
433    ) -> jni_sys::jdouble;
434
435    unsafe fn call_static_double_method(
436        class: &Class,
437        method_id: jni_sys::jmethodID,
438        arguments: Self,
439    ) -> jni_sys::jdouble;
440}
441
442macro_rules! jni_method_call {
443    ($name:ident, $type:ty, $method:ident, $return_type:ty, $($argument:ident,)*) => {
444        unsafe fn $name(
445            object: &$type,
446            method_id: jni_sys::jmethodID,
447            arguments: Self
448        ) -> $return_type {
449            #[allow(non_snake_case)]
450            let ($($argument,)*) = arguments;
451            call_jni_method!(
452                object.env(),
453                $method,
454                object.raw_object(),
455                method_id
456                $(,ToJni::__to_jni(&$argument))*
457            )
458        }
459    }
460}
461
462macro_rules! peel_input_tuple_impls {
463    () => ();
464    ($type:ident, $jni_type:ident, $($other:ident,)*) => (input_tuple_impls! { $($other,)* });
465}
466
467macro_rules! input_tuple_impls {
468    ( $($type:ident, $jni_type:ident,)*) => (
469        impl<'a, $($type, $jni_type),*> ToJniTuple for ($($type,)*)
470        where
471            $($type: ToJni<__JniType = $jni_type>,)*
472            $($jni_type: JniArgumentType),*
473        {
474            jni_method_call!(call_constructor, Class, NewObject, jni_sys::jobject, $($type,)*);
475            jni_method_call!(call_object_method, Object, CallObjectMethod, jni_sys::jobject, $($type,)*);
476            jni_method_call!(call_static_object_method, Class, CallStaticObjectMethod, jni_sys::jobject, $($type,)*);
477            jni_method_call!(call_void_method, Object, CallVoidMethod, (), $($type,)*);
478            jni_method_call!(call_static_void_method, Class, CallStaticVoidMethod, (), $($type,)*);
479            jni_method_call!(call_boolean_method, Object, CallBooleanMethod, jni_sys::jboolean, $($type,)*);
480            jni_method_call!(call_static_boolean_method, Class, CallStaticBooleanMethod, jni_sys::jboolean, $($type,)*);
481            jni_method_call!(call_char_method, Object, CallCharMethod, jni_sys::jchar, $($type,)*);
482            jni_method_call!(call_static_char_method, Class, CallStaticCharMethod, jni_sys::jchar, $($type,)*);
483            jni_method_call!(call_byte_method, Object, CallByteMethod, jni_sys::jbyte, $($type,)*);
484            jni_method_call!(call_static_byte_method, Class, CallStaticByteMethod, jni_sys::jbyte, $($type,)*);
485            jni_method_call!(call_short_method, Object, CallShortMethod, jni_sys::jshort, $($type,)*);
486            jni_method_call!(call_static_short_method, Class, CallStaticShortMethod, jni_sys::jshort, $($type,)*);
487            jni_method_call!(call_int_method, Object, CallIntMethod, jni_sys::jint, $($type,)*);
488            jni_method_call!(call_static_int_method, Class, CallStaticIntMethod, jni_sys::jint, $($type,)*);
489            jni_method_call!(call_long_method, Object, CallLongMethod, jni_sys::jlong, $($type,)*);
490            jni_method_call!(call_static_long_method, Class, CallStaticLongMethod, jni_sys::jlong, $($type,)*);
491            jni_method_call!(call_float_method, Object, CallFloatMethod, jni_sys::jfloat, $($type,)*);
492            jni_method_call!(call_static_float_method, Class, CallStaticFloatMethod, jni_sys::jfloat, $($type,)*);
493            jni_method_call!(call_double_method, Object, CallDoubleMethod, jni_sys::jdouble, $($type,)*);
494            jni_method_call!(call_static_double_method, Class, CallStaticDoubleMethod, jni_sys::jdouble, $($type,)*);
495        }
496        peel_input_tuple_impls! { $($type, $jni_type,)* }
497    );
498}
499
500input_tuple_impls! {
501    T0, T0Jni,
502    T1, T1Jni,
503    T2, T2Jni,
504    T3, T3Jni,
505    T4, T4Jni,
506    T5, T5Jni,
507    T6, T6Jni,
508    T7, T7Jni,
509    T8, T8Jni,
510    T9, T9Jni,
511    T10, T10Jni,
512    T11, T11Jni,
513}
514
515#[cfg(test)]
516macro_rules! generate_to_jni_tuple_tests {
517    (
518        $jni_type:ty,
519        $default:expr,
520        $result:expr,
521        $method:ident,
522        $jni_method:ident,
523        $static_method:ident,
524        $jni_static_method:ident
525    ) => {
526        #[test]
527        fn $method() {
528            static mut METHOD_CALLS: i32 = 0;
529            static mut METHOD_ENV_ARGUMENT: *mut jni_sys::JNIEnv = ptr::null_mut();
530            static mut METHOD_OBJECT_ARGUMENT: jni_sys::jobject = ptr::null_mut();
531            static mut METHOD_METHOD_ARGUMENT: jni_sys::jmethodID = ptr::null_mut();
532            static mut METHOD_ARGUMENT0: jni_sys::jint = 0;
533            static mut METHOD_ARGUMENT1: jni_sys::jdouble = 0.;
534            static mut METHOD_RESULT: $jni_type = $default;
535            type VariadicFn = unsafe extern "C" fn(
536                env: *mut jni_sys::JNIEnv,
537                object: jni_sys::jobject,
538                method_id: jni_sys::jmethodID,
539                ...
540            ) -> $jni_type;
541            type TestFn = unsafe extern "C" fn(
542                env: *mut jni_sys::JNIEnv,
543                object: jni_sys::jobject,
544                method_id: jni_sys::jmethodID,
545                argument0: jni_sys::jint,
546                argument1: jni_sys::jdouble,
547            ) -> $jni_type;
548            unsafe extern "C" fn method(
549                env: *mut jni_sys::JNIEnv,
550                object: jni_sys::jobject,
551                method_id: jni_sys::jmethodID,
552                argument0: jni_sys::jint,
553                argument1: jni_sys::jdouble,
554            ) -> $jni_type {
555                METHOD_CALLS += 1;
556                METHOD_ENV_ARGUMENT = env;
557                METHOD_OBJECT_ARGUMENT = object;
558                METHOD_METHOD_ARGUMENT = method_id;
559                METHOD_ARGUMENT0 = argument0;
560                METHOD_ARGUMENT1 = argument1;
561                METHOD_RESULT
562            }
563            let vm = test_vm(ptr::null_mut());
564            let raw_jni_env = jni_sys::JNINativeInterface_ {
565                $jni_method: Some(unsafe { mem::transmute::<TestFn, VariadicFn>(method) }),
566                ..empty_raw_jni_env()
567            };
568            let raw_jni_env = &mut (&raw_jni_env as jni_sys::JNIEnv) as *mut jni_sys::JNIEnv;
569            let env = test_env(&vm, raw_jni_env);
570            let raw_object = 0x91011 as jni_sys::jobject;
571            let object = test_object(&env, raw_object);
572            let method_id = 0x7654 as jni_sys::jmethodID;
573            let arguments = (17 as i32, 19. as f64);
574            let result = $result;
575            unsafe {
576                METHOD_RESULT = result;
577                assert_eq!(ToJniTuple::$method(&object, method_id, arguments), result);
578                assert_eq!(METHOD_CALLS, 1);
579                assert_eq!(METHOD_ENV_ARGUMENT, raw_jni_env);
580                assert_eq!(METHOD_OBJECT_ARGUMENT, raw_object);
581                assert_eq!(METHOD_METHOD_ARGUMENT, method_id);
582                assert_eq!(METHOD_ARGUMENT0, arguments.0);
583                assert_eq!(METHOD_ARGUMENT1, arguments.1);
584            }
585        }
586
587        #[test]
588        fn $static_method() {
589            static mut METHOD_CALLS: i32 = 0;
590            static mut METHOD_ENV_ARGUMENT: *mut jni_sys::JNIEnv = ptr::null_mut();
591            static mut METHOD_OBJECT_ARGUMENT: jni_sys::jobject = ptr::null_mut();
592            static mut METHOD_METHOD_ARGUMENT: jni_sys::jmethodID = ptr::null_mut();
593            static mut METHOD_ARGUMENT0: jni_sys::jint = 0;
594            static mut METHOD_ARGUMENT1: jni_sys::jdouble = 0.;
595            static mut METHOD_RESULT: $jni_type = $default;
596            type VariadicFn = unsafe extern "C" fn(
597                env: *mut jni_sys::JNIEnv,
598                object: jni_sys::jobject,
599                method_id: jni_sys::jmethodID,
600                ...
601            ) -> $jni_type;
602            type TestFn = unsafe extern "C" fn(
603                env: *mut jni_sys::JNIEnv,
604                object: jni_sys::jobject,
605                method_id: jni_sys::jmethodID,
606                argument0: jni_sys::jint,
607                argument1: jni_sys::jdouble,
608            ) -> $jni_type;
609            unsafe extern "C" fn method(
610                env: *mut jni_sys::JNIEnv,
611                object: jni_sys::jobject,
612                method_id: jni_sys::jmethodID,
613                argument0: jni_sys::jint,
614                argument1: jni_sys::jdouble,
615            ) -> $jni_type {
616                METHOD_CALLS += 1;
617                METHOD_ENV_ARGUMENT = env;
618                METHOD_OBJECT_ARGUMENT = object;
619                METHOD_METHOD_ARGUMENT = method_id;
620                METHOD_ARGUMENT0 = argument0;
621                METHOD_ARGUMENT1 = argument1;
622                METHOD_RESULT
623            }
624            let vm = test_vm(ptr::null_mut());
625            let raw_jni_env = jni_sys::JNINativeInterface_ {
626                $jni_static_method: Some(unsafe { mem::transmute::<TestFn, VariadicFn>(method) }),
627                ..empty_raw_jni_env()
628            };
629            let raw_jni_env = &mut (&raw_jni_env as jni_sys::JNIEnv) as *mut jni_sys::JNIEnv;
630            let env = test_env(&vm, raw_jni_env);
631            let raw_object = 0x91011 as jni_sys::jobject;
632            let class = test_class(&env, raw_object);
633            let method_id = 0x7654 as jni_sys::jmethodID;
634            let arguments = (17 as i32, 19. as f64);
635            let result = $result;
636            unsafe {
637                METHOD_RESULT = result;
638                assert_eq!(
639                    ToJniTuple::$static_method(&class, method_id, arguments),
640                    result
641                );
642                assert_eq!(METHOD_CALLS, 1);
643                assert_eq!(METHOD_ENV_ARGUMENT, raw_jni_env);
644                assert_eq!(METHOD_OBJECT_ARGUMENT, raw_object);
645                assert_eq!(METHOD_METHOD_ARGUMENT, method_id);
646                assert_eq!(METHOD_ARGUMENT0, arguments.0);
647                assert_eq!(METHOD_ARGUMENT1, arguments.1);
648            }
649        }
650    };
651}
652
653#[cfg(test)]
654mod to_jni_tuple_tests {
655    use super::*;
656    use jni::testing::*;
657    use std::mem;
658
659    generate_to_jni_tuple_tests!(
660        jni_sys::jobject,
661        ptr::null_mut() as jni_sys::jobject,
662        0x1234 as jni_sys::jobject,
663        call_object_method,
664        CallObjectMethod,
665        call_static_object_method,
666        CallStaticObjectMethod
667    );
668
669    generate_to_jni_tuple_tests!(
670        (),
671        (),
672        (),
673        call_void_method,
674        CallVoidMethod,
675        call_static_void_method,
676        CallStaticVoidMethod
677    );
678
679    generate_to_jni_tuple_tests!(
680        jni_sys::jboolean,
681        jni_sys::JNI_FALSE,
682        jni_sys::JNI_TRUE,
683        call_boolean_method,
684        CallBooleanMethod,
685        call_static_boolean_method,
686        CallStaticBooleanMethod
687    );
688
689    generate_to_jni_tuple_tests!(
690        jni_sys::jchar,
691        0,
692        42,
693        call_char_method,
694        CallCharMethod,
695        call_static_char_method,
696        CallStaticCharMethod
697    );
698
699    generate_to_jni_tuple_tests!(
700        jni_sys::jbyte,
701        0,
702        42,
703        call_byte_method,
704        CallByteMethod,
705        call_static_byte_method,
706        CallStaticByteMethod
707    );
708
709    generate_to_jni_tuple_tests!(
710        jni_sys::jshort,
711        0,
712        42,
713        call_short_method,
714        CallShortMethod,
715        call_static_short_method,
716        CallStaticShortMethod
717    );
718
719    generate_to_jni_tuple_tests!(
720        jni_sys::jint,
721        0,
722        42,
723        call_int_method,
724        CallIntMethod,
725        call_static_int_method,
726        CallStaticIntMethod
727    );
728
729    generate_to_jni_tuple_tests!(
730        jni_sys::jlong,
731        0,
732        42,
733        call_long_method,
734        CallLongMethod,
735        call_static_long_method,
736        CallStaticLongMethod
737    );
738
739    generate_to_jni_tuple_tests!(
740        jni_sys::jfloat,
741        0.,
742        42.,
743        call_float_method,
744        CallFloatMethod,
745        call_static_float_method,
746        CallStaticFloatMethod
747    );
748
749    generate_to_jni_tuple_tests!(
750        jni_sys::jdouble,
751        0.,
752        42.,
753        call_double_method,
754        CallDoubleMethod,
755        call_static_double_method,
756        CallStaticDoubleMethod
757    );
758
759    #[test]
760    fn call_constructor() {
761        // TODO(#25): test `f32` as well.
762        static mut METHOD_CALLS: i32 = 0;
763        static mut METHOD_ENV_ARGUMENT: *mut jni_sys::JNIEnv = ptr::null_mut();
764        static mut METHOD_OBJECT_ARGUMENT: jni_sys::jobject = ptr::null_mut();
765        static mut METHOD_METHOD_ARGUMENT: jni_sys::jmethodID = ptr::null_mut();
766        static mut METHOD_ARGUMENT0: jni_sys::jboolean = 0;
767        static mut METHOD_ARGUMENT1: jni_sys::jchar = 0;
768        static mut METHOD_ARGUMENT2: jni_sys::jbyte = 0;
769        static mut METHOD_ARGUMENT3: jni_sys::jshort = 0;
770        static mut METHOD_ARGUMENT4: jni_sys::jint = 0;
771        static mut METHOD_ARGUMENT5: jni_sys::jlong = 0;
772        static mut METHOD_ARGUMENT7: jni_sys::jdouble = 0.;
773        static mut METHOD_ARGUMENT8: jni_sys::jint = 0;
774        static mut METHOD_ARGUMENT9: jni_sys::jint = 0;
775        static mut METHOD_ARGUMENT10: jni_sys::jint = 0;
776        static mut METHOD_ARGUMENT11: jni_sys::jint = 0;
777        static mut METHOD_ARGUMENT12: jni_sys::jint = 0;
778        static mut METHOD_RESULT: jni_sys::jobject = ptr::null_mut();
779        type VariadicFn = unsafe extern "C" fn(
780            env: *mut jni_sys::JNIEnv,
781            object: jni_sys::jobject,
782            method_id: jni_sys::jmethodID,
783            ...
784        ) -> jni_sys::jobject;
785        type TestFn = unsafe extern "C" fn(
786            env: *mut jni_sys::JNIEnv,
787            object: jni_sys::jobject,
788            method_id: jni_sys::jmethodID,
789            argument0: jni_sys::jboolean,
790            argument1: jni_sys::jchar,
791            argument2: jni_sys::jbyte,
792            argument3: jni_sys::jshort,
793            argument4: jni_sys::jint,
794            argument5: jni_sys::jlong,
795            argument7: jni_sys::jdouble,
796            argument8: jni_sys::jint,
797            argument9: jni_sys::jint,
798            argument10: jni_sys::jint,
799            argument11: jni_sys::jint,
800            argument12: jni_sys::jint,
801        ) -> jni_sys::jobject;
802        unsafe extern "C" fn method(
803            env: *mut jni_sys::JNIEnv,
804            object: jni_sys::jobject,
805            method_id: jni_sys::jmethodID,
806            argument0: jni_sys::jboolean,
807            argument1: jni_sys::jchar,
808            argument2: jni_sys::jbyte,
809            argument3: jni_sys::jshort,
810            argument4: jni_sys::jint,
811            argument5: jni_sys::jlong,
812            argument7: jni_sys::jdouble,
813            argument8: jni_sys::jint,
814            argument9: jni_sys::jint,
815            argument10: jni_sys::jint,
816            argument11: jni_sys::jint,
817            argument12: jni_sys::jint,
818        ) -> jni_sys::jobject {
819            METHOD_CALLS += 1;
820            METHOD_ENV_ARGUMENT = env;
821            METHOD_OBJECT_ARGUMENT = object;
822            METHOD_METHOD_ARGUMENT = method_id;
823            METHOD_ARGUMENT0 = argument0;
824            METHOD_ARGUMENT1 = argument1;
825            METHOD_ARGUMENT2 = argument2;
826            METHOD_ARGUMENT3 = argument3;
827            METHOD_ARGUMENT4 = argument4;
828            METHOD_ARGUMENT5 = argument5;
829            METHOD_ARGUMENT7 = argument7;
830            METHOD_ARGUMENT8 = argument8;
831            METHOD_ARGUMENT9 = argument9;
832            METHOD_ARGUMENT10 = argument10;
833            METHOD_ARGUMENT11 = argument11;
834            METHOD_ARGUMENT12 = argument12;
835            METHOD_RESULT
836        }
837        let vm = test_vm(ptr::null_mut());
838        let raw_jni_env = jni_sys::JNINativeInterface_ {
839            NewObject: Some(unsafe { mem::transmute::<TestFn, VariadicFn>(method) }),
840            ..empty_raw_jni_env()
841        };
842        let raw_jni_env = &mut (&raw_jni_env as jni_sys::JNIEnv) as *mut jni_sys::JNIEnv;
843        let env = test_env(&vm, raw_jni_env);
844        let raw_object = 0x91011 as jni_sys::jobject;
845        let class = test_class(&env, raw_object);
846        let method_id = 0x7654 as jni_sys::jmethodID;
847        let arguments = (
848            true, 'h', 15 as u8, 16 as i16, 17 as i32, 18 as i64, 20. as f64, 21 as i32, 22 as i32,
849            23 as i32, 24 as i32, 25 as i32,
850        );
851        let result = 0x1234 as jni_sys::jobject;
852        unsafe {
853            METHOD_RESULT = result;
854            assert_eq!(
855                ToJniTuple::call_constructor(&class, method_id, arguments),
856                result
857            );
858            assert_eq!(METHOD_CALLS, 1);
859            assert_eq!(METHOD_ENV_ARGUMENT, raw_jni_env);
860            assert_eq!(METHOD_OBJECT_ARGUMENT, raw_object);
861            assert_eq!(METHOD_METHOD_ARGUMENT, method_id);
862            assert_eq!(METHOD_ARGUMENT0, arguments.0.__to_jni());
863            assert_eq!(METHOD_ARGUMENT1, arguments.1.__to_jni());
864            assert_eq!(METHOD_ARGUMENT2, arguments.2.__to_jni());
865            assert_eq!(METHOD_ARGUMENT3, arguments.3.__to_jni());
866            assert_eq!(METHOD_ARGUMENT4, arguments.4.__to_jni());
867            assert_eq!(METHOD_ARGUMENT5, arguments.5.__to_jni());
868            assert_eq!(METHOD_ARGUMENT7, arguments.6.__to_jni());
869            assert_eq!(METHOD_ARGUMENT8, arguments.7.__to_jni());
870            assert_eq!(METHOD_ARGUMENT9, arguments.8.__to_jni());
871            assert_eq!(METHOD_ARGUMENT10, arguments.9.__to_jni());
872            assert_eq!(METHOD_ARGUMENT11, arguments.10.__to_jni());
873            assert_eq!(METHOD_ARGUMENT12, arguments.11.__to_jni());
874        }
875    }
876}
877
878impl JniArgumentType for jni_sys::jboolean {}
879impl JniArgumentType for jni_sys::jchar {}
880impl JniArgumentType for jni_sys::jbyte {}
881impl JniArgumentType for jni_sys::jshort {}
882impl JniArgumentType for jni_sys::jint {}
883impl JniArgumentType for jni_sys::jlong {}
884impl JniArgumentType for jni_sys::jfloat {}
885impl JniArgumentType for jni_sys::jdouble {}
886impl JniArgumentType for jni_sys::jobject {}
887
888/// Make [`bool`](https://doc.rust-lang.org/std/primitive.bool.html) mappable to
889/// [`jboolean`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jboolean.html).
890impl JavaType for bool {
891    #[doc(hidden)]
892    type __JniType = jni_sys::jboolean;
893
894    #[doc(hidden)]
895    fn __signature() -> &'static str {
896        "Z"
897    }
898}
899
900/// Make [`bool`](https://doc.rust-lang.org/std/primitive.bool.html) convertible to
901/// [`jboolean`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jboolean.html).
902impl ToJni for bool {
903    unsafe fn __to_jni(&self) -> Self::__JniType {
904        match self {
905            true => jni_sys::JNI_TRUE,
906            false => jni_sys::JNI_FALSE,
907        }
908    }
909}
910
911/// Make [`bool`](https://doc.rust-lang.org/std/primitive.bool.html) convertible from
912/// [`jboolean`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jboolean.html).
913impl<'env> FromJni<'env> for bool {
914    unsafe fn __from_jni(_: &'env JniEnv<'env>, value: Self::__JniType) -> Self {
915        match value {
916            jni_sys::JNI_TRUE => true,
917            jni_sys::JNI_FALSE => false,
918            value => panic!("Unexpected jboolean value {:?}", value),
919        }
920    }
921}
922
923#[cfg(test)]
924mod bool_tests {
925    use super::*;
926
927    #[test]
928    fn signature() {
929        assert_eq!(bool::__signature(), "Z");
930    }
931
932    #[test]
933    fn to_jni() {
934        unsafe {
935            assert_eq!(true.__to_jni(), jni_sys::JNI_TRUE);
936            assert_eq!(false.__to_jni(), jni_sys::JNI_FALSE);
937        }
938    }
939
940    #[test]
941    fn from_jni() {
942        let vm = test_vm(ptr::null_mut());
943        let env = test_env(&vm, ptr::null_mut());
944        unsafe {
945            assert_eq!(bool::__from_jni(&env, jni_sys::JNI_TRUE), true);
946            assert_eq!(bool::__from_jni(&env, jni_sys::JNI_FALSE), false);
947        }
948    }
949
950    #[test]
951    fn to_and_from() {
952        let vm = test_vm(ptr::null_mut());
953        let env = test_env(&vm, ptr::null_mut());
954        unsafe {
955            assert_eq!(bool::__from_jni(&env, true.__to_jni()), true);
956            assert_eq!(bool::__from_jni(&env, false.__to_jni()), false);
957        }
958    }
959
960    #[test]
961    fn from_and_to() {
962        let vm = test_vm(ptr::null_mut());
963        let env = test_env(&vm, ptr::null_mut());
964        unsafe {
965            assert_eq!(
966                bool::__from_jni(&env, jni_sys::JNI_TRUE).__to_jni(),
967                jni_sys::JNI_TRUE
968            );
969            assert_eq!(
970                bool::__from_jni(&env, jni_sys::JNI_FALSE).__to_jni(),
971                jni_sys::JNI_FALSE
972            );
973        }
974    }
975}
976
977/// Make [`char`](https://doc.rust-lang.org/std/primitive.char.html) mappable to
978/// [`jchar`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jchar.html).
979impl JavaType for char {
980    #[doc(hidden)]
981    type __JniType = jni_sys::jchar;
982
983    #[doc(hidden)]
984    fn __signature() -> &'static str {
985        "C"
986    }
987}
988
989/// Make [`char`](https://doc.rust-lang.org/std/primitive.char.html) convertible to
990/// [`jchar`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jchar.html).
991#[doc(hidden)]
992impl ToJni for char {
993    unsafe fn __to_jni(&self) -> Self::__JniType {
994        *self as Self::__JniType
995    }
996}
997
998/// Make [`char`](https://doc.rust-lang.org/std/primitive.char.html) convertible from
999/// [`jchar`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jchar.html).
1000#[doc(hidden)]
1001impl<'env> FromJni<'env> for char {
1002    unsafe fn __from_jni(_: &'env JniEnv<'env>, value: Self::__JniType) -> Self {
1003        let mut decoder = char::decode_utf16(iter::once(value));
1004        // A character returned from Java is guaranteed to be a valid UTF-16 code point.
1005        let character = decoder.next().unwrap().unwrap();
1006        match decoder.next() {
1007            None => {}
1008            Some(second) => {
1009                panic!(
1010                    "Java character {:?} was mapped to more than one Rust characters: \
1011                     [{:?}, {:?}, ...].",
1012                    value, character, second,
1013                );
1014            }
1015        }
1016        character
1017    }
1018}
1019
1020#[cfg(test)]
1021mod char_tests {
1022    use super::*;
1023
1024    #[test]
1025    fn signature() {
1026        assert_eq!(char::__signature(), "C");
1027    }
1028
1029    #[test]
1030    fn to_jni() {
1031        unsafe {
1032            assert_eq!('h'.__to_jni(), 'h' as jni_sys::jchar);
1033        }
1034    }
1035
1036    #[test]
1037    fn from_jni() {
1038        let vm = test_vm(ptr::null_mut());
1039        let env = test_env(&vm, ptr::null_mut());
1040        unsafe {
1041            assert_eq!(char::__from_jni(&env, 'h' as jni_sys::jchar), 'h');
1042        }
1043    }
1044
1045    #[test]
1046    fn to_and_from() {
1047        let vm = test_vm(ptr::null_mut());
1048        let env = test_env(&vm, ptr::null_mut());
1049        unsafe {
1050            assert_eq!(char::__from_jni(&env, 'h'.__to_jni()), 'h');
1051        }
1052    }
1053
1054    #[test]
1055    fn from_and_to() {
1056        let vm = test_vm(ptr::null_mut());
1057        let env = test_env(&vm, ptr::null_mut());
1058        unsafe {
1059            assert_eq!(
1060                char::__from_jni(&env, 'h' as jni_sys::jchar).__to_jni(),
1061                'h' as jni_sys::jchar
1062            );
1063        }
1064    }
1065}
1066
1067/// A macro for generating [`JavaType`](trait.JavaType.html) implementations for most primitive
1068/// Rust types.
1069macro_rules! jni_io_traits {
1070    ($type:ty, $jni_type:ty, $signature:expr, $link:expr, $jni_sys_link:expr) => {
1071        /// Make
1072        #[doc = $link]
1073        /// mappable to
1074        #[doc = $jni_sys_link]
1075        ///.
1076        impl JavaType for $type {
1077            #[doc(hidden)]
1078            type __JniType = $jni_type;
1079
1080            #[doc(hidden)]
1081            fn __signature() -> &'static str {
1082                $signature
1083            }
1084        }
1085
1086        /// Make
1087        #[doc = $link]
1088        /// convertible to
1089        #[doc = $jni_sys_link]
1090        ///.
1091        #[doc(hidden)]
1092        impl ToJni for $type {
1093            unsafe fn __to_jni(&self) -> Self::__JniType {
1094                *self as Self::__JniType
1095            }
1096        }
1097
1098        /// Make
1099        #[doc = $link]
1100        /// convertible from
1101        #[doc = $jni_sys_link]
1102        ///.
1103        #[doc(hidden)]
1104        impl<'env> FromJni<'env> for $type {
1105            unsafe fn __from_jni(_: &'env JniEnv<'env>, value: Self::__JniType) -> Self {
1106                value as Self
1107            }
1108        }
1109    };
1110}
1111
1112jni_io_traits!(
1113    (),
1114    (),
1115    "V",
1116    "[`()`](https://doc.rust-lang.org/std/primitive.unit.html)",
1117    "[`()`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jchar.html)"
1118);
1119jni_io_traits!(
1120    u8,
1121    jni_sys::jbyte,
1122    "B",
1123    "[`u8`](https://doc.rust-lang.org/std/primitive.u8.html)",
1124    "[`jbyte`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jbyte.html)"
1125);
1126jni_io_traits!(
1127    i16,
1128    jni_sys::jshort,
1129    "S",
1130    "[`i16`](https://doc.rust-lang.org/std/primitive.i16.html)",
1131    "[`jshort`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jshort.html)"
1132);
1133jni_io_traits!(
1134    i32,
1135    jni_sys::jint,
1136    "I",
1137    "[`i32`](https://doc.rust-lang.org/std/primitive.i32.html)",
1138    "[`jint`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jint.html)"
1139);
1140jni_io_traits!(
1141    i64,
1142    jni_sys::jlong,
1143    "J",
1144    "[`i64`](https://doc.rust-lang.org/std/primitive.i64.html)",
1145    "[`jlong`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jlong.html)"
1146);
1147// For some reason, floats need to be passed as 64-bit floats to JNI.
1148// When passed as 32-bit numbers, Java recieves `0.0` instead of the passed number.
1149// This also causes `__JniType` to not reside in `JavaType`, as this is the
1150// only exceptional case.
1151// TODO(#25): figure out the underlying cause of this.
1152// native call -> java: f64
1153// java -> native call: f32
1154// java -> native method: f64
1155// native method -> java: f64
1156// jni_io_traits!(
1157//     f32,
1158//     jni_sys::jfloat,
1159//     "F",
1160//     "[`f32`](https://doc.rust-lang.org/std/primitive.f32.html)",
1161//     "[`jfloat`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jfloat.html)"
1162// );
1163jni_io_traits!(
1164    f64,
1165    jni_sys::jdouble,
1166    "D",
1167    "[`f64`](https://doc.rust-lang.org/std/primitive.f64.html)",
1168    "[`jdouble`](https://docs.rs/jni-sys/0.3.0/jni_sys/type.jdouble.html)"
1169);
1170
1171#[cfg(test)]
1172mod void_tests {
1173    use super::*;
1174
1175    #[test]
1176    fn signature() {
1177        assert_eq!(<()>::__signature(), "V");
1178    }
1179
1180    #[test]
1181    fn to_jni() {
1182        unsafe {
1183            assert_eq!(().__to_jni(), ());
1184        }
1185    }
1186
1187    #[test]
1188    fn from_jni() {
1189        let vm = test_vm(ptr::null_mut());
1190        let env = test_env(&vm, ptr::null_mut());
1191        unsafe {
1192            assert_eq!(<()>::__from_jni(&env, ()), ());
1193        }
1194    }
1195
1196    #[test]
1197    fn to_and_from() {
1198        let vm = test_vm(ptr::null_mut());
1199        let env = test_env(&vm, ptr::null_mut());
1200        unsafe {
1201            assert_eq!(<()>::__from_jni(&env, ().__to_jni()), ());
1202        }
1203    }
1204
1205    #[test]
1206    fn from_and_to() {
1207        let vm = test_vm(ptr::null_mut());
1208        let env = test_env(&vm, ptr::null_mut());
1209        unsafe {
1210            assert_eq!(<()>::__from_jni(&env, ()).__to_jni(), ());
1211        }
1212    }
1213}
1214
1215#[cfg(test)]
1216mod byte_tests {
1217    use super::*;
1218
1219    #[test]
1220    fn signature() {
1221        assert_eq!(u8::__signature(), "B");
1222    }
1223
1224    #[test]
1225    fn to_jni() {
1226        unsafe {
1227            assert_eq!(217.__to_jni(), 217);
1228        }
1229    }
1230
1231    #[test]
1232    fn from_jni() {
1233        let vm = test_vm(ptr::null_mut());
1234        let env = test_env(&vm, ptr::null_mut());
1235        unsafe {
1236            assert_eq!(u8::__from_jni(&env, 217 as u8 as i8), 217);
1237        }
1238    }
1239
1240    #[test]
1241    fn to_and_from() {
1242        let vm = test_vm(ptr::null_mut());
1243        let env = test_env(&vm, ptr::null_mut());
1244        unsafe {
1245            assert_eq!(u8::__from_jni(&env, (217 as u8).__to_jni()), 217);
1246        }
1247    }
1248
1249    #[test]
1250    fn from_and_to() {
1251        let vm = test_vm(ptr::null_mut());
1252        let env = test_env(&vm, ptr::null_mut());
1253        unsafe {
1254            assert_eq!(
1255                u8::__from_jni(&env, 217 as u8 as i8).__to_jni(),
1256                217 as u8 as i8
1257            );
1258        }
1259    }
1260}
1261
1262#[cfg(test)]
1263mod short_tests {
1264
1265    #[test]
1266    fn signature() {
1267        assert_eq!(i16::__signature(), "S");
1268    }
1269    use super::*;
1270
1271    #[test]
1272    fn to_jni() {
1273        unsafe {
1274            assert_eq!(217.__to_jni(), 217);
1275        }
1276    }
1277
1278    #[test]
1279    fn from_jni() {
1280        let vm = test_vm(ptr::null_mut());
1281        let env = test_env(&vm, ptr::null_mut());
1282        unsafe {
1283            assert_eq!(i16::__from_jni(&env, 217), 217);
1284        }
1285    }
1286
1287    #[test]
1288    fn to_and_from() {
1289        let vm = test_vm(ptr::null_mut());
1290        let env = test_env(&vm, ptr::null_mut());
1291        unsafe {
1292            assert_eq!(i16::__from_jni(&env, (217 as i16).__to_jni()), 217);
1293        }
1294    }
1295
1296    #[test]
1297    fn from_and_to() {
1298        let vm = test_vm(ptr::null_mut());
1299        let env = test_env(&vm, ptr::null_mut());
1300        unsafe {
1301            assert_eq!(i16::__from_jni(&env, 217).__to_jni(), 217);
1302        }
1303    }
1304}
1305
1306#[cfg(test)]
1307mod int_tests {
1308    use super::*;
1309
1310    #[test]
1311    fn signature() {
1312        assert_eq!(i32::__signature(), "I");
1313    }
1314
1315    #[test]
1316    fn to_jni() {
1317        unsafe {
1318            assert_eq!(217.__to_jni(), 217);
1319        }
1320    }
1321
1322    #[test]
1323    fn from_jni() {
1324        let vm = test_vm(ptr::null_mut());
1325        let env = test_env(&vm, ptr::null_mut());
1326        unsafe {
1327            assert_eq!(i32::__from_jni(&env, 217), 217);
1328        }
1329    }
1330
1331    #[test]
1332    fn to_and_from() {
1333        let vm = test_vm(ptr::null_mut());
1334        let env = test_env(&vm, ptr::null_mut());
1335        unsafe {
1336            assert_eq!(i32::__from_jni(&env, (217 as i32).__to_jni()), 217);
1337        }
1338    }
1339
1340    #[test]
1341    fn from_and_to() {
1342        let vm = test_vm(ptr::null_mut());
1343        let env = test_env(&vm, ptr::null_mut());
1344        unsafe {
1345            assert_eq!(i32::__from_jni(&env, 217).__to_jni(), 217);
1346        }
1347    }
1348}
1349
1350#[cfg(test)]
1351mod long_tests {
1352    use super::*;
1353
1354    #[test]
1355    fn signature() {
1356        assert_eq!(i64::__signature(), "J");
1357    }
1358
1359    #[test]
1360    fn to_jni() {
1361        unsafe {
1362            assert_eq!(217.__to_jni(), 217);
1363        }
1364    }
1365
1366    #[test]
1367    fn from_jni() {
1368        let vm = test_vm(ptr::null_mut());
1369        let env = test_env(&vm, ptr::null_mut());
1370        unsafe {
1371            assert_eq!(i64::__from_jni(&env, 217), 217);
1372        }
1373    }
1374
1375    #[test]
1376    fn to_and_from() {
1377        let vm = test_vm(ptr::null_mut());
1378        let env = test_env(&vm, ptr::null_mut());
1379        unsafe {
1380            assert_eq!(i64::__from_jni(&env, (217 as i64).__to_jni()), 217);
1381        }
1382    }
1383
1384    #[test]
1385    fn from_and_to() {
1386        let vm = test_vm(ptr::null_mut());
1387        let env = test_env(&vm, ptr::null_mut());
1388        unsafe {
1389            assert_eq!(i64::__from_jni(&env, 217).__to_jni(), 217);
1390        }
1391    }
1392}
1393
1394#[cfg(test)]
1395mod double_tests {
1396    use super::*;
1397
1398    #[test]
1399    fn signature() {
1400        assert_eq!(f64::__signature(), "D");
1401    }
1402
1403    #[test]
1404    fn to_jni() {
1405        unsafe {
1406            assert_eq!((217.).__to_jni(), 217.);
1407        }
1408    }
1409
1410    #[test]
1411    fn from_jni() {
1412        let vm = test_vm(ptr::null_mut());
1413        let env = test_env(&vm, ptr::null_mut());
1414        unsafe {
1415            assert_eq!(f64::__from_jni(&env, 217.), 217.);
1416        }
1417    }
1418
1419    #[test]
1420    fn to_and_from() {
1421        let vm = test_vm(ptr::null_mut());
1422        let env = test_env(&vm, ptr::null_mut());
1423        unsafe {
1424            assert_eq!(f64::__from_jni(&env, (217. as f64).__to_jni()), 217.);
1425        }
1426    }
1427
1428    #[test]
1429    fn from_and_to() {
1430        let vm = test_vm(ptr::null_mut());
1431        let env = test_env(&vm, ptr::null_mut());
1432        unsafe {
1433            assert_eq!(f64::__from_jni(&env, 217.).__to_jni(), 217.);
1434        }
1435    }
1436}