1 use crate::sys::jfieldID;
2 
3 /// Wrapper around [`jfieldID`] that implements `Send` + `Sync` since method IDs
4 /// are valid across threads (not tied to a `JNIEnv`).
5 ///
6 /// There is no lifetime associated with these since they aren't garbage
7 /// collected like objects and their lifetime is not implicitly connected with
8 /// the scope in which they are queried.
9 ///
10 /// It matches C's representation of the raw pointer, so it can be used in any
11 /// of the extern function argument positions that would take a [`jfieldID`].
12 ///
13 /// # Safety
14 ///
15 /// According to the JNI spec field IDs may be invalidated when the
16 /// corresponding class is unloaded.
17 ///
18 /// Since this constraint can't be encoded as a Rust lifetime, and to avoid the
19 /// excessive cost of having every Method ID be associated with a global
20 /// reference to the corresponding class then it is the developers
21 /// responsibility to ensure they hold some class reference for the lifetime of
22 /// cached method IDs.
23 #[repr(transparent)]
24 #[derive(Copy, Clone)]
25 pub struct JFieldID {
26     internal: jfieldID,
27 }
28 
29 // Field IDs are valid across threads (not tied to a JNIEnv)
30 unsafe impl Send for JFieldID {}
31 unsafe impl Sync for JFieldID {}
32 
33 impl JFieldID {
34     /// Creates a [`JFieldID`] that wraps the given `raw` [`jfieldID`]
35     ///
36     /// # Safety
37     ///
38     /// Expects a valid, non-`null` ID
from_raw(raw: jfieldID) -> Self39     pub unsafe fn from_raw(raw: jfieldID) -> Self {
40         debug_assert!(!raw.is_null(), "from_raw fieldID argument");
41         Self { internal: raw }
42     }
43 
44     /// Unwrap to the internal jni type.
into_raw(self) -> jfieldID45     pub fn into_raw(self) -> jfieldID {
46         self.internal
47     }
48 }
49 
50 impl AsRef<JFieldID> for JFieldID {
as_ref(&self) -> &JFieldID51     fn as_ref(&self) -> &JFieldID {
52         self
53     }
54 }
55 
56 impl AsMut<JFieldID> for JFieldID {
as_mut(&mut self) -> &mut JFieldID57     fn as_mut(&mut self) -> &mut JFieldID {
58         self
59     }
60 }
61