1use typed_jni_core::{Arg, JNIEnv, MethodID, StrongRef};
2
3use crate::{LocalObject, Null, Object, ObjectType, Signature, Type, builtin::JavaThrowable, call::target::Target};
4
5pub trait ToArg {
12 fn to_arg(&self) -> Arg<'_>;
13}
14
15macro_rules! impl_to_arg_primitive {
16 ($t:ty, $variant:ident) => {
17 impl ToArg for $t {
18 fn to_arg(&self) -> Arg<'_> {
19 Arg::$variant(*self)
20 }
21 }
22 };
23}
24
25impl_to_arg_primitive!(bool, Boolean);
26impl_to_arg_primitive!(i8, Byte);
27impl_to_arg_primitive!(u16, Char);
28impl_to_arg_primitive!(i16, Short);
29impl_to_arg_primitive!(i32, Int);
30impl_to_arg_primitive!(i64, Long);
31impl_to_arg_primitive!(f32, Float);
32impl_to_arg_primitive!(f64, Double);
33
34impl<R: StrongRef, T: ObjectType> ToArg for Object<R, T> {
35 fn to_arg(&self) -> Arg<'_> {
36 Arg::Object(Some(&**self))
37 }
38}
39
40impl<R: StrongRef, T: ObjectType> ToArg for Option<Object<R, T>> {
41 fn to_arg(&self) -> Arg<'_> {
42 match self {
43 Some(obj) => Arg::Object(Some(&**obj)),
44 None => Arg::Object(None),
45 }
46 }
47}
48
49impl<R: StrongRef, T: ObjectType> ToArg for &Object<R, T> {
50 fn to_arg(&self) -> Arg<'_> {
51 Arg::Object(Some(&***self))
52 }
53}
54
55impl<R: StrongRef, T: ObjectType> ToArg for Option<&Object<R, T>> {
56 fn to_arg(&self) -> Arg<'_> {
57 match self {
58 Some(obj) => Arg::Object(Some(&***obj)),
59 None => Arg::Object(None),
60 }
61 }
62}
63
64impl<T: ObjectType> ToArg for Null<T> {
65 fn to_arg(&self) -> Arg<'_> {
66 Arg::Object(None)
67 }
68}
69
70pub unsafe trait Args: Sized {
76 fn signature(&self) -> impl IntoIterator<Item = Signature> + Clone + '_;
77
78 unsafe fn apply_on<'env, const STATIC: bool, T, R>(
84 self,
85 env: &'env JNIEnv,
86 this: &T,
87 method: MethodID<STATIC>,
88 ) -> Result<R, LocalObject<'env, JavaThrowable>>
89 where
90 T: StrongRef,
91 R: Target<'env>;
92}
93
94unsafe impl Args for () {
95 fn signature(&self) -> impl IntoIterator<Item = Signature> + Clone + '_ {
96 []
97 }
98
99 unsafe fn apply_on<'env, const STATIC: bool, T, R>(
100 self,
101 env: &'env JNIEnv,
102 this: &T,
103 method: MethodID<STATIC>,
104 ) -> Result<R, LocalObject<'env, JavaThrowable>>
105 where
106 T: StrongRef,
107 R: Target<'env>,
108 {
109 unsafe { R::call(env, this, method, []) }
110 }
111}
112
113macro_rules! impl_fixed_args {
114 ($($n:ident),*) => {
115 unsafe impl<$($n: ToArg + Type),*> Args for ($($n,)*) {
116 fn signature(&self) -> impl IntoIterator<Item = Signature> + Clone + '_ {
117 [$($n::SIGNATURE,)*]
118 }
119
120 unsafe fn apply_on<'env, const STATIC: bool, T, R>(
121 self,
122 env: &'env JNIEnv,
123 this: &T,
124 method: MethodID<STATIC>,
125 ) -> Result<R, LocalObject<'env, JavaThrowable>>
126 where
127 T: StrongRef,
128 R: Target<'env>,
129 {
130 unsafe {
131 #[allow(non_snake_case)]
132 let ($($n,)*) = self;
133
134 R::call(env, this, method, [$($n.to_arg(),)*])
135 }
136 }
137 }
138 };
139}
140
141#[rustfmt::skip]
142const _: () = {
143 impl_fixed_args!(A1);
144 impl_fixed_args!(A1, A2);
145 impl_fixed_args!(A1, A2, A3);
146 impl_fixed_args!(A1, A2, A3, A4);
147 impl_fixed_args!(A1, A2, A3, A4, A5);
148 impl_fixed_args!(A1, A2, A3, A4, A5, A6);
149 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7);
150 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8);
151 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9);
152 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
153 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11);
154 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12);
155 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13);
156 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14);
157 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15);
158 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16);
159 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17);
160 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18);
161 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19);
162 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20);
163 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21);
164 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22);
165 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23);
166 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24);
167 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25);
168 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26);
169 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27);
170 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28);
171 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29);
172 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30);
173 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31);
174 impl_fixed_args!(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32);
175};
176
177pub trait DynArg: ToArg {
179 fn signature(&self) -> Signature;
180}
181
182impl<T: Type + ToArg> DynArg for T {
183 fn signature(&self) -> Signature {
184 T::SIGNATURE
185 }
186}
187
188unsafe impl Args for &[&dyn DynArg] {
189 fn signature(&self) -> impl IntoIterator<Item = Signature> + Clone + '_ {
190 self.iter().map(|arg| arg.signature())
191 }
192
193 unsafe fn apply_on<'env, const STATIC: bool, T, R>(
194 self,
195 env: &'env JNIEnv,
196 this: &T,
197 method: MethodID<STATIC>,
198 ) -> Result<R, LocalObject<'env, JavaThrowable>>
199 where
200 T: StrongRef,
201 R: Target<'env>,
202 {
203 unsafe { R::call_variadic(env, this, method, self.iter().map(|arg| arg.to_arg())) }
204 }
205}
206
207unsafe impl<const N: usize> Args for [&dyn DynArg; N] {
208 fn signature(&self) -> impl IntoIterator<Item = Signature> + Clone + '_ {
209 self.map(|arg| arg.signature())
210 }
211
212 unsafe fn apply_on<'env, const STATIC: bool, T, R>(
213 self,
214 env: &'env JNIEnv,
215 this: &T,
216 method: MethodID<STATIC>,
217 ) -> Result<R, LocalObject<'env, JavaThrowable>>
218 where
219 T: StrongRef,
220 R: Target<'env>,
221 {
222 unsafe { R::call(env, this, method, self.map(|arg| arg.to_arg())) }
223 }
224}
225
226unsafe impl<const N: usize> Args for &[&dyn DynArg; N] {
227 fn signature(&self) -> impl IntoIterator<Item = Signature> + Clone + '_ {
228 (*self).signature()
229 }
230
231 unsafe fn apply_on<'env, const STATIC: bool, T, R>(
232 self,
233 env: &'env JNIEnv,
234 this: &T,
235 method: MethodID<STATIC>,
236 ) -> Result<R, LocalObject<'env, JavaThrowable>>
237 where
238 T: StrongRef,
239 R: Target<'env>,
240 {
241 unsafe { (*self).apply_on(env, this, method) }
242 }
243}