1use typed_jni_core::{JNIEnv, LocalRef, StrongRef};
2
3use crate::{LocalObject, Null, Object, ObjectType, TypedRef, builtin::JavaThrowable, core::FieldID};
4
5pub unsafe trait Value {
16 unsafe fn set_on<'env, const STATIC: bool, R: StrongRef>(
22 self,
23 env: &'env JNIEnv,
24 this: &R,
25 field: FieldID<STATIC>,
26 ) -> Result<(), LocalObject<'env, JavaThrowable>>;
27}
28
29macro_rules! impl_value_for_primitive {
30 ($typ:ty, $set:ident) => {
31 unsafe impl Value for $typ {
32 unsafe fn set_on<'env, const STATIC: bool, R: StrongRef>(
33 self,
34 env: &'env JNIEnv,
35 this: &R,
36 field: FieldID<STATIC>,
37 ) -> Result<(), LocalObject<'env, JavaThrowable>> {
38 unsafe { env.$set(this, field, self).map_err(|err| LocalObject::from_ref(err)) }
39 }
40 }
41 };
42}
43
44impl_value_for_primitive!(bool, set_boolean_field);
45impl_value_for_primitive!(i8, set_byte_field);
46impl_value_for_primitive!(u16, set_char_field);
47impl_value_for_primitive!(i16, set_short_field);
48impl_value_for_primitive!(i32, set_int_field);
49impl_value_for_primitive!(i64, set_long_field);
50impl_value_for_primitive!(f32, set_float_field);
51impl_value_for_primitive!(f64, set_double_field);
52
53macro_rules! impl_value_for_object {
54 ($typ:ty, $value:ident, $extract:block) => {
55 unsafe impl<Ref: StrongRef, Type: ObjectType> Value for $typ {
56 unsafe fn set_on<'env, const STATIC: bool, R: StrongRef>(
57 self,
58 env: &'env JNIEnv,
59 this: &R,
60 field: FieldID<STATIC>,
61 ) -> Result<(), LocalObject<'env, JavaThrowable>> {
62 unsafe {
63 let $value = self;
64
65 env.set_object_field(this, field, $extract)
66 .map_err(|err| LocalObject::from_ref(err))
67 }
68 }
69 }
70 };
71}
72
73impl_value_for_object!(Option<Object<Ref, Type>>, value, { value.as_deref() });
74impl_value_for_object!(Option<&Object<Ref, Type>>, value, { value.as_ref().map(|v| &***v) });
75impl_value_for_object!(Object<Ref, Type>, value, { Some(&*value) });
76impl_value_for_object!(&Object<Ref, Type>, value, { Some(&**value) });
77
78unsafe impl<T: ObjectType> Value for Null<T> {
79 unsafe fn set_on<'env, const STATIC: bool, R: StrongRef>(
80 self,
81 env: &'env JNIEnv,
82 this: &R,
83 field: FieldID<STATIC>,
84 ) -> Result<(), LocalObject<'env, JavaThrowable>> {
85 unsafe {
86 env.set_object_field(this, field, Option::<&LocalRef>::None)
87 .map_err(|err| LocalObject::from_ref(err))
88 }
89 }
90}