1use std::any::Any;
16use std::convert::TryFrom;
17use std::ptr;
18
19use jni_sys::{jobject, JNIEnv};
20use serde::Serialize;
21use serde_json;
22
23use crate::api::instance::Instance;
24use crate::api::{JavaClass, Jvm, Null};
25use crate::{cache, errors, jni_utils, utils};
26
27#[derive(Serialize)]
29pub enum InvocationArg {
30 Java {
32 instance: Instance,
33 class_name: String,
34 serialized: bool,
35 },
36 Rust {
38 json: String,
39 class_name: String,
40 serialized: bool,
41 },
42 RustBasic {
46 instance: Instance,
47 class_name: String,
48 serialized: bool,
49 },
50}
51
52impl InvocationArg {
53
54 pub fn empty<'a>() -> &'a[InvocationArg;0] {
56 &[]
57 }
58
59 pub fn new<T>(arg: &T, class_name: &str) -> InvocationArg
62 where
63 T: Serialize + Any,
64 {
65 Self::new_2(
66 arg,
67 class_name,
68 cache::get_thread_local_env().expect("Could not find the jni_env in the local cache. Please make sure that you created a Jvm before using Jvm::new"))
69 .expect("Could not create the InvocationArg. Please see the logs/console for more details.")
70 }
71
72 pub fn new_2<T>(
73 arg: &T,
74 class_name: &str,
75 jni_env: *mut JNIEnv,
76 ) -> errors::Result<InvocationArg>
77 where
78 T: Serialize + Any,
79 {
80 let arg_any = arg as &dyn Any;
81 if let Some(a) = arg_any.downcast_ref::<String>() {
82 Ok(InvocationArg::RustBasic {
83 instance: Instance::new(
84 jni_utils::global_jobject_from_str(a, jni_env)?,
85 class_name,
86 )?,
87 class_name: class_name.to_string(),
88 serialized: false,
89 })
90 } else if let Some(a) = arg_any.downcast_ref::<i8>() {
91 Ok(InvocationArg::RustBasic {
92 instance: Instance::new(
93 jni_utils::global_jobject_from_i8(a, jni_env)?,
94 class_name,
95 )?,
96 class_name: class_name.to_string(),
97 serialized: false,
98 })
99 } else if let Some(a) = arg_any.downcast_ref::<i16>() {
100 Ok(InvocationArg::RustBasic {
101 instance: Instance::new(
102 jni_utils::global_jobject_from_i16(a, jni_env)?,
103 class_name,
104 )?,
105 class_name: class_name.to_string(),
106 serialized: false,
107 })
108 } else if let Some(a) = arg_any.downcast_ref::<i32>() {
109 Ok(InvocationArg::RustBasic {
110 instance: Instance::new(
111 jni_utils::global_jobject_from_i32(a, jni_env)?,
112 class_name,
113 )?,
114 class_name: class_name.to_string(),
115 serialized: false,
116 })
117 } else if let Some(a) = arg_any.downcast_ref::<i64>() {
118 Ok(InvocationArg::RustBasic {
119 instance: Instance::new(
120 jni_utils::global_jobject_from_i64(a, jni_env)?,
121 class_name,
122 )?,
123 class_name: class_name.to_string(),
124 serialized: false,
125 })
126 } else if let Some(a) = arg_any.downcast_ref::<f32>() {
127 Ok(InvocationArg::RustBasic {
128 instance: Instance::new(
129 jni_utils::global_jobject_from_f32(a, jni_env)?,
130 class_name,
131 )?,
132 class_name: class_name.to_string(),
133 serialized: false,
134 })
135 } else if let Some(a) = arg_any.downcast_ref::<f64>() {
136 Ok(InvocationArg::RustBasic {
137 instance: Instance::new(
138 jni_utils::global_jobject_from_f64(a, jni_env)?,
139 class_name,
140 )?,
141 class_name: class_name.to_string(),
142 serialized: false,
143 })
144 } else {
145 let json = serde_json::to_string(arg)?;
146 Ok(InvocationArg::Rust {
147 json: json,
148 class_name: class_name.to_string(),
149 serialized: true,
150 })
151 }
152 }
153
154 fn make_primitive(&mut self) -> errors::Result<()> {
155 match utils::primitive_of(self) {
156 Some(primitive_repr) => {
157 match self {
158 &mut InvocationArg::Java {
159 instance: _,
160 ref mut class_name,
161 serialized: _,
162 } => *class_name = primitive_repr,
163 &mut InvocationArg::Rust {
164 json: _,
165 ref mut class_name,
166 serialized: _,
167 } => *class_name = primitive_repr,
168 &mut InvocationArg::RustBasic {
169 instance: _,
170 ref mut class_name,
171 serialized: _,
172 } => *class_name = primitive_repr,
173 };
174 Ok(())
175 }
176 None => Err(errors::J4RsError::JavaError(format!(
177 "Cannot transform to primitive: {}",
178 utils::get_class_name(&self)
179 ))),
180 }
181 }
182
183 pub fn into_primitive(self) -> errors::Result<InvocationArg> {
188 let mut ia = self;
189 ia.make_primitive()?;
190 Ok(ia)
191 }
192
193 pub fn as_java_ptr_with_global_ref(&self, jni_env: *mut JNIEnv) -> errors::Result<jobject> {
195 match self {
196 _s @ &InvocationArg::Java { .. } => {
197 jni_utils::invocation_arg_jobject_from_java(&self, jni_env, true)
198 }
199 _s @ &InvocationArg::Rust { .. } => {
200 jni_utils::invocation_arg_jobject_from_rust_serialized(&self, jni_env, true)
201 }
202 _s @ &InvocationArg::RustBasic { .. } => {
203 jni_utils::invocation_arg_jobject_from_rust_basic(&self, jni_env, true)
204 }
205 }
206 }
207
208 pub fn as_java_ptr_with_local_ref(&self, jni_env: *mut JNIEnv) -> errors::Result<jobject> {
210 match self {
211 _s @ &InvocationArg::Java { .. } => {
212 jni_utils::invocation_arg_jobject_from_java(&self, jni_env, false)
213 }
214 _s @ &InvocationArg::Rust { .. } => {
215 jni_utils::invocation_arg_jobject_from_rust_serialized(&self, jni_env, false)
216 }
217 _s @ &InvocationArg::RustBasic { .. } => {
218 jni_utils::invocation_arg_jobject_from_rust_basic(&self, jni_env, false)
219 }
220 }
221 }
222
223 pub fn instance(self) -> errors::Result<Instance> {
225 match self {
226 InvocationArg::Java { instance: i, .. } => Ok(i),
227 InvocationArg::RustBasic { .. } => Err(errors::J4RsError::RustError(format!(
228 "Invalid operation: Cannot get the instance of an InvocationArg::RustBasic"
229 ))),
230 InvocationArg::Rust { .. } => Err(errors::J4RsError::RustError(format!(
231 "Cannot get the instance from an InvocationArg::Rust"
232 ))),
233 }
234 }
235
236 pub fn class_name(&self) -> &str {
237 match self {
238 &InvocationArg::Java {
239 instance: _,
240 ref class_name,
241 serialized: _,
242 } => class_name,
243 &InvocationArg::Rust {
244 json: _,
245 ref class_name,
246 serialized: _,
247 } => class_name,
248 &InvocationArg::RustBasic {
249 instance: _,
250 ref class_name,
251 serialized: _,
252 } => class_name,
253 }
254 }
255
256 pub fn create_null(null: Null) -> errors::Result<InvocationArg> {
258 let class_name: &str = match null {
259 Null::String => JavaClass::String,
260 Null::Boolean => JavaClass::Boolean,
261 Null::Byte => JavaClass::Byte,
262 Null::Character => JavaClass::Character,
263 Null::Short => JavaClass::Short,
264 Null::Integer => JavaClass::Integer,
265 Null::Long => JavaClass::Long,
266 Null::Float => JavaClass::Float,
267 Null::Double => JavaClass::Double,
268 Null::List => JavaClass::List,
269 Null::Of(class_name) => JavaClass::Of(class_name),
270 }
271 .into();
272 Ok(InvocationArg::RustBasic {
273 instance: Instance::new(ptr::null_mut(), class_name)?,
274 class_name: class_name.to_string(),
275 serialized: false,
276 })
277 }
278}
279
280impl From<Instance> for InvocationArg {
281 fn from(instance: Instance) -> InvocationArg {
282 let class_name = instance.class_name.to_owned();
283
284 InvocationArg::Java {
285 instance: instance,
286 class_name: class_name,
287 serialized: false,
288 }
289 }
290}
291
292impl TryFrom<Result<Instance, errors::J4RsError>> for InvocationArg {
293 type Error = errors::J4RsError;
294
295 fn try_from(
296 instance_res: Result<Instance, errors::J4RsError>,
297 ) -> errors::Result<InvocationArg> {
298 Ok(InvocationArg::from(instance_res?))
299 }
300}
301
302impl<'a> TryFrom<Null<'a>> for InvocationArg {
303 type Error = errors::J4RsError;
304 fn try_from(null: Null) -> errors::Result<InvocationArg> {
305 InvocationArg::create_null(null)
306 }
307}
308
309impl TryFrom<String> for InvocationArg {
310 type Error = errors::J4RsError;
311 fn try_from(arg: String) -> errors::Result<InvocationArg> {
312 InvocationArg::new_2(
313 &arg,
314 JavaClass::String.into(),
315 cache::get_thread_local_env()?,
316 )
317 }
318}
319
320impl<'a> TryFrom<&'a [String]> for InvocationArg {
321 type Error = errors::J4RsError;
322 fn try_from(vec: &'a [String]) -> errors::Result<InvocationArg> {
323 let args: errors::Result<Vec<InvocationArg>> = vec
324 .iter()
325 .map(|elem| InvocationArg::try_from(elem))
326 .collect();
327 let res =
328 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
329 Ok(InvocationArg::from(res?))
330 }
331}
332
333impl<'a> TryFrom<&'a str> for InvocationArg {
334 type Error = errors::J4RsError;
335 fn try_from(arg: &'a str) -> errors::Result<InvocationArg> {
336 InvocationArg::new_2(
337 &arg.to_string(),
338 JavaClass::String.into(),
339 cache::get_thread_local_env()?,
340 )
341 }
342}
343
344impl<'a> TryFrom<&'a [&'a str]> for InvocationArg {
345 type Error = errors::J4RsError;
346 fn try_from(vec: &'a [&'a str]) -> errors::Result<InvocationArg> {
347 let args: errors::Result<Vec<InvocationArg>> = vec
348 .iter()
349 .map(|&elem| InvocationArg::try_from(elem))
350 .collect();
351 let res =
352 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
353 Ok(InvocationArg::from(res?))
354 }
355}
356
357impl TryFrom<bool> for InvocationArg {
358 type Error = errors::J4RsError;
359 fn try_from(arg: bool) -> errors::Result<InvocationArg> {
360 InvocationArg::new_2(
361 &arg,
362 JavaClass::Boolean.into(),
363 cache::get_thread_local_env()?,
364 )
365 }
366}
367
368impl<'a> TryFrom<&'a [bool]> for InvocationArg {
369 type Error = errors::J4RsError;
370 fn try_from(vec: &'a [bool]) -> errors::Result<InvocationArg> {
371 let args: errors::Result<Vec<InvocationArg>> = vec
372 .iter()
373 .map(|elem| InvocationArg::try_from(elem))
374 .collect();
375 let res =
376 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
377 Ok(InvocationArg::from(res?))
378 }
379}
380
381impl TryFrom<i8> for InvocationArg {
382 type Error = errors::J4RsError;
383 fn try_from(arg: i8) -> errors::Result<InvocationArg> {
384 InvocationArg::new_2(&arg, JavaClass::Byte.into(), cache::get_thread_local_env()?)
385 }
386}
387
388impl<'a> TryFrom<&'a [i8]> for InvocationArg {
389 type Error = errors::J4RsError;
390 fn try_from(vec: &'a [i8]) -> errors::Result<InvocationArg> {
391 let args: errors::Result<Vec<InvocationArg>> = vec
392 .iter()
393 .map(|elem| InvocationArg::try_from(elem))
394 .collect();
395 let res =
396 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
397 Ok(InvocationArg::from(res?))
398 }
399}
400
401impl TryFrom<char> for InvocationArg {
402 type Error = errors::J4RsError;
403 fn try_from(arg: char) -> errors::Result<InvocationArg> {
404 InvocationArg::new_2(
405 &arg,
406 JavaClass::Character.into(),
407 cache::get_thread_local_env()?,
408 )
409 }
410}
411
412impl<'a> TryFrom<&'a [char]> for InvocationArg {
413 type Error = errors::J4RsError;
414 fn try_from(vec: &'a [char]) -> errors::Result<InvocationArg> {
415 let args: errors::Result<Vec<InvocationArg>> = vec
416 .iter()
417 .map(|elem| InvocationArg::try_from(elem))
418 .collect();
419 let res =
420 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
421 Ok(InvocationArg::from(res?))
422 }
423}
424
425impl TryFrom<i16> for InvocationArg {
426 type Error = errors::J4RsError;
427 fn try_from(arg: i16) -> errors::Result<InvocationArg> {
428 InvocationArg::new_2(
429 &arg,
430 JavaClass::Short.into(),
431 cache::get_thread_local_env()?,
432 )
433 }
434}
435
436impl<'a> TryFrom<&'a [i16]> for InvocationArg {
437 type Error = errors::J4RsError;
438 fn try_from(vec: &'a [i16]) -> errors::Result<InvocationArg> {
439 let args: errors::Result<Vec<InvocationArg>> = vec
440 .iter()
441 .map(|elem| InvocationArg::try_from(elem))
442 .collect();
443 let res =
444 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
445 Ok(InvocationArg::from(res?))
446 }
447}
448
449impl TryFrom<i32> for InvocationArg {
450 type Error = errors::J4RsError;
451 fn try_from(arg: i32) -> errors::Result<InvocationArg> {
452 InvocationArg::new_2(
453 &arg,
454 JavaClass::Integer.into(),
455 cache::get_thread_local_env()?,
456 )
457 }
458}
459
460impl<'a> TryFrom<&'a [i32]> for InvocationArg {
461 type Error = errors::J4RsError;
462 fn try_from(vec: &'a [i32]) -> errors::Result<InvocationArg> {
463 let args: errors::Result<Vec<InvocationArg>> = vec
464 .iter()
465 .map(|elem| InvocationArg::try_from(elem))
466 .collect();
467 let res =
468 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
469 Ok(InvocationArg::from(res?))
470 }
471}
472
473impl TryFrom<i64> for InvocationArg {
474 type Error = errors::J4RsError;
475 fn try_from(arg: i64) -> errors::Result<InvocationArg> {
476 InvocationArg::new_2(&arg, JavaClass::Long.into(), cache::get_thread_local_env()?)
477 }
478}
479
480impl<'a> TryFrom<&'a [i64]> for InvocationArg {
481 type Error = errors::J4RsError;
482 fn try_from(vec: &'a [i64]) -> errors::Result<InvocationArg> {
483 let args: errors::Result<Vec<InvocationArg>> = vec
484 .iter()
485 .map(|elem| InvocationArg::try_from(elem))
486 .collect();
487 let res =
488 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
489 Ok(InvocationArg::from(res?))
490 }
491}
492
493impl TryFrom<f32> for InvocationArg {
494 type Error = errors::J4RsError;
495 fn try_from(arg: f32) -> errors::Result<InvocationArg> {
496 InvocationArg::new_2(
497 &arg,
498 JavaClass::Float.into(),
499 cache::get_thread_local_env()?,
500 )
501 }
502}
503
504impl<'a> TryFrom<&'a [f32]> for InvocationArg {
505 type Error = errors::J4RsError;
506 fn try_from(vec: &'a [f32]) -> errors::Result<InvocationArg> {
507 let args: errors::Result<Vec<InvocationArg>> = vec
508 .iter()
509 .map(|elem| InvocationArg::try_from(elem))
510 .collect();
511 let res =
512 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
513 Ok(InvocationArg::from(res?))
514 }
515}
516
517impl TryFrom<f64> for InvocationArg {
518 type Error = errors::J4RsError;
519 fn try_from(arg: f64) -> errors::Result<InvocationArg> {
520 InvocationArg::new_2(
521 &arg,
522 JavaClass::Double.into(),
523 cache::get_thread_local_env()?,
524 )
525 }
526}
527
528impl<'a> TryFrom<&'a [f64]> for InvocationArg {
529 type Error = errors::J4RsError;
530 fn try_from(vec: &'a [f64]) -> errors::Result<InvocationArg> {
531 let args: errors::Result<Vec<InvocationArg>> = vec
532 .iter()
533 .map(|elem| InvocationArg::try_from(elem))
534 .collect();
535 let res =
536 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
537 Ok(InvocationArg::from(res?))
538 }
539}
540
541impl TryFrom<()> for InvocationArg {
542 type Error = errors::J4RsError;
543 fn try_from(arg: ()) -> errors::Result<InvocationArg> {
544 InvocationArg::new_2(&arg, JavaClass::Void.into(), cache::get_thread_local_env()?)
545 }
546}
547
548impl<'a> TryFrom<&'a String> for InvocationArg {
549 type Error = errors::J4RsError;
550 fn try_from(arg: &'a String) -> errors::Result<InvocationArg> {
551 InvocationArg::new_2(
552 arg,
553 JavaClass::String.into(),
554 cache::get_thread_local_env()?,
555 )
556 }
557}
558
559impl<'a> TryFrom<&'a bool> for InvocationArg {
560 type Error = errors::J4RsError;
561 fn try_from(arg: &'a bool) -> errors::Result<InvocationArg> {
562 InvocationArg::new_2(
563 arg,
564 JavaClass::Boolean.into(),
565 cache::get_thread_local_env()?,
566 )
567 }
568}
569
570impl<'a> TryFrom<&'a i8> for InvocationArg {
571 type Error = errors::J4RsError;
572 fn try_from(arg: &'a i8) -> errors::Result<InvocationArg> {
573 InvocationArg::new_2(arg, JavaClass::Byte.into(), cache::get_thread_local_env()?)
574 }
575}
576
577impl<'a> TryFrom<&'a char> for InvocationArg {
578 type Error = errors::J4RsError;
579 fn try_from(arg: &'a char) -> errors::Result<InvocationArg> {
580 InvocationArg::new_2(
581 arg,
582 JavaClass::Character.into(),
583 cache::get_thread_local_env()?,
584 )
585 }
586}
587
588impl<'a> TryFrom<&'a i16> for InvocationArg {
589 type Error = errors::J4RsError;
590 fn try_from(arg: &'a i16) -> errors::Result<InvocationArg> {
591 InvocationArg::new_2(arg, JavaClass::Short.into(), cache::get_thread_local_env()?)
592 }
593}
594
595impl<'a, 'b> TryFrom<&'a i32> for InvocationArg {
596 type Error = errors::J4RsError;
597 fn try_from(arg: &'a i32) -> errors::Result<InvocationArg> {
598 InvocationArg::new_2(
599 arg,
600 JavaClass::Integer.into(),
601 cache::get_thread_local_env()?,
602 )
603 }
604}
605
606impl<'a> TryFrom<&'a i64> for InvocationArg {
607 type Error = errors::J4RsError;
608 fn try_from(arg: &'a i64) -> errors::Result<InvocationArg> {
609 InvocationArg::new_2(arg, JavaClass::Long.into(), cache::get_thread_local_env()?)
610 }
611}
612
613impl<'a> TryFrom<&'a f32> for InvocationArg {
614 type Error = errors::J4RsError;
615 fn try_from(arg: &'a f32) -> errors::Result<InvocationArg> {
616 InvocationArg::new_2(arg, JavaClass::Float.into(), cache::get_thread_local_env()?)
617 }
618}
619
620impl<'a> TryFrom<&'a f64> for InvocationArg {
621 type Error = errors::J4RsError;
622 fn try_from(arg: &'a f64) -> errors::Result<InvocationArg> {
623 InvocationArg::new_2(
624 arg,
625 JavaClass::Double.into(),
626 cache::get_thread_local_env()?,
627 )
628 }
629}
630
631impl<'a, T: 'static> TryFrom<(&'a [T], &'a str)> for InvocationArg
632 where
633 T: Serialize,
634{
635 type Error = errors::J4RsError;
636 fn try_from(vec: (&'a [T], &'a str)) -> errors::Result<InvocationArg> {
637 let (vec, elements_class_name) = vec;
638 let jni_env = cache::get_thread_local_env()?;
639 let args: errors::Result<Vec<InvocationArg>> = vec
640 .iter()
641 .map(|elem| {
642 InvocationArg::new_2(elem, JavaClass::Of(elements_class_name).into(), jni_env)
643 })
644 .collect();
645 let res =
646 Jvm::do_create_java_list(cache::get_thread_local_env()?, cache::J4RS_ARRAY, &args?);
647 Ok(InvocationArg::from(res?))
648 }
649}
650
651impl TryFrom<Result<InvocationArg, errors::J4RsError>> for InvocationArg {
652 type Error = errors::J4RsError;
653 fn try_from(arg: Result<InvocationArg, errors::J4RsError>) -> errors::Result<InvocationArg> {
654 arg
655 }
656}
657
658#[cfg(test)]
659mod inv_arg_unit_tests {
660 use serde::Deserialize;
661
662 use crate::{api, errors, JvmBuilder, MavenArtifact};
663
664 use super::*;
665
666 fn create_tests_jvm() -> errors::Result<Jvm> {
667 let jvm: Jvm = JvmBuilder::new().build()?;
668 jvm.deploy_artifact(&MavenArtifact::from(format!("io.github.astonbitecode:j4rs-testing:{}", api::j4rs_version()).as_str()))?;
669 Ok(jvm)
670 }
671
672 #[test]
673 fn new_invocation_arg() -> errors::Result<()> {
674 let _jvm = create_tests_jvm()?;
675 let _ = InvocationArg::new(&"something".to_string(), "somethingelse");
676
677 Ok(())
678 }
679
680 #[test]
681 fn invocation_arg_try_from_basic_types() -> errors::Result<()> {
682 let _jvm = create_tests_jvm()?;
683 validate_type(InvocationArg::try_from("str")?, "java.lang.String");
684 validate_type(
685 InvocationArg::try_from("str".to_string())?,
686 "java.lang.String",
687 );
688 validate_type(InvocationArg::try_from(true)?, "java.lang.Boolean");
689 validate_type(InvocationArg::try_from(1_i8)?, "java.lang.Byte");
690 validate_type(InvocationArg::try_from('c')?, "java.lang.Character");
691 validate_type(InvocationArg::try_from(1_i16)?, "java.lang.Short");
692 validate_type(InvocationArg::try_from(1_i64)?, "java.lang.Long");
693 validate_type(InvocationArg::try_from(0.1_f32)?, "java.lang.Float");
694 validate_type(
695 InvocationArg::try_from(0.1_f64)?,
696 "java.lang.Double",
697 );
698 validate_type(InvocationArg::try_from(())?, "void");
699
700 validate_type(
701 InvocationArg::try_from(&"str".to_string())?,
702 "java.lang.String",
703 );
704 validate_type(InvocationArg::try_from("str")?, "java.lang.String");
705 validate_type(InvocationArg::try_from(&true)?, "java.lang.Boolean");
706 validate_type(InvocationArg::try_from(&1_i8)?, "java.lang.Byte");
707 validate_type(
708 InvocationArg::try_from(&'c')?,
709 "java.lang.Character",
710 );
711 validate_type(InvocationArg::try_from(&1_i16)?, "java.lang.Short");
712 validate_type(InvocationArg::try_from(&1_i64)?, "java.lang.Long");
713 validate_type(
714 InvocationArg::try_from(&0.1_f32)?,
715 "java.lang.Float",
716 );
717 validate_type(
718 InvocationArg::try_from(&0.1_f64)?,
719 "java.lang.Double",
720 );
721
722 Ok(())
723 }
724
725 #[test]
726 fn invocation_into_primitive() -> errors::Result<()> {
727 let _jvm: Jvm = create_tests_jvm()?;
728 assert!(InvocationArg::try_from(false)?
729 .into_primitive()
730 .is_ok());
731 assert!(InvocationArg::try_from(1_i8)?
732 .into_primitive()
733 .is_ok());
734 assert!(InvocationArg::try_from(1_i16)?
735 .into_primitive()
736 .is_ok());
737 assert!(InvocationArg::try_from(1_i32)?
738 .into_primitive()
739 .is_ok());
740 assert!(InvocationArg::try_from(1_i64)?
741 .into_primitive()
742 .is_ok());
743 assert!(InvocationArg::try_from(0.1_f32)?
744 .into_primitive()
745 .is_ok());
746 assert!(InvocationArg::try_from(0.1_f64)?
747 .into_primitive()
748 .is_ok());
749 assert!(InvocationArg::try_from('c')?
750 .into_primitive()
751 .is_ok());
752 assert!(InvocationArg::try_from(())?
753 .into_primitive()
754 .is_ok());
755 assert!(InvocationArg::try_from("string")?
756 .into_primitive()
757 .is_err());
758
759 Ok(())
760 }
761
762 #[test]
763 fn invocation_arg_for_custom_types() -> errors::Result<()> {
764 let jvm = create_tests_jvm()?;
765
766 let my_bean = MyBean {
767 someString: "My String In A Bean".to_string(),
768 someInteger: 33,
769 };
770 let ia = InvocationArg::new(&my_bean, "org.astonbitecode.j4rs.tests.MyBean");
771
772 let test_instance = jvm.create_instance("org.astonbitecode.j4rs.tests.MyTest", InvocationArg::empty())?;
773 let string_instance = jvm.invoke(&test_instance, "getTheString", &[ia]).unwrap();
774
775 let rust_string: String = jvm.to_rust(string_instance).unwrap();
776
777 assert!(&rust_string == "My String In A Bean");
778
779 Ok(())
780 }
781
782 #[derive(Serialize, Deserialize, Debug)]
783 #[allow(non_snake_case)]
784 struct MyBean {
785 someString: String,
786 someInteger: isize,
787 }
788
789 fn validate_type(ia: InvocationArg, class: &str) {
790 let b = match ia {
791 _s @ InvocationArg::Java { .. } => false,
792 InvocationArg::Rust {
793 class_name,
794 json: _,
795 ..
796 } => class == class_name,
797 InvocationArg::RustBasic {
798 instance: _,
799 class_name,
800 serialized: _,
801 } => class == class_name,
802 };
803 assert!(b);
804 }
805}