jni_pointer/
lib.rs

1use std::ops::Deref;
2#[allow(non_camel_case_types)]
3type jlong = i64;
4
5#[allow(non_camel_case_types)]
6pub type jptr = jlong;
7
8#[derive(Debug)]
9pub struct Pointer<Kind> {
10    value: Box<Kind>,
11}
12
13impl<Kind> Pointer<Kind> {
14    pub fn new(value: Kind) -> Self {
15        Pointer {
16            value: Box::new(value),
17        }
18    }
19
20    pub fn borrow<'a>(self) -> &'a mut Kind {
21        Box::leak(self.value)
22    }
23}
24
25impl<Kind> From<Pointer<Kind>> for jptr {
26    fn from(pointer: Pointer<Kind>) -> Self {
27        Box::into_raw(pointer.value) as _
28    }
29}
30
31impl<Kind> From<jptr> for Pointer<Kind> {
32    fn from(pointer: jptr) -> Self {
33        Self {
34            value: unsafe { Box::from_raw(pointer as *mut Kind) },
35        }
36    }
37}
38
39impl<Kind> Deref for Pointer<Kind> {
40    type Target = Kind;
41
42    fn deref(&self) -> &Self::Target {
43        &self.value
44    }
45}
46#[cfg(test)]
47mod tests {
48    use crate::{jlong, Pointer};
49
50    struct Value {
51        num: i64,
52        s: String
53    }
54
55    #[test]
56    pub fn can_recover_value_from_pointer(){
57        let value = Value {
58            num: 6,
59            s: "Some string".into()
60        };
61        let pointer: Pointer<_> = Pointer::new(value);
62        let pointer_n: jlong = pointer.into();
63        let pointer2: Pointer<Value> = pointer_n.into();
64        assert_eq!(pointer2.s, Into::<String>::into("Some string"));
65        assert_eq!(pointer2.num, 6);
66    }
67}