typed_jni/field/
set.rs

1use typed_jni_core::{JNIEnv, LocalRef, StrongRef};
2
3use crate::{LocalObject, Null, Object, ObjectType, TypedRef, builtin::JavaThrowable, core::FieldID};
4
5/// This trait is implemented for all types that can be the argument of a field set operation.
6///
7/// Supported Types:
8///
9/// * Primitive types: `bool`, `i8`, `u16`, `i32`, `i64`, `f32`, `f64`
10/// * Object types: `Object<impl StrongRef, Type>`, `Option<Object<impl StrongRef, Type>>`
11///
12/// # Safety
13///
14/// This trait should not be implemented manually.
15pub unsafe trait Value {
16    /// Set the value of a field.
17    ///
18    /// # Safety
19    ///
20    /// * Signature of `Self` must match the signature of `field`.
21    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}