kimchi_stubs/caml/
shared_reference.rs

1//! `impl_shared_reference1 implements an OCaml
2//! custom type that wraps around a shared reference to a Rust object.
3
4macro_rules! impl_shared_reference {
5    ($name: ident => $typ: ty) => {
6        #[derive(Debug, ::ocaml_gen::CustomType)]
7        pub struct $name(pub ::std::sync::Arc<$typ>);
8
9        //
10        // necessary ocaml.rs stuff
11        //
12
13        impl $name {
14            extern "C" fn caml_pointer_finalize(v: ::ocaml::Raw) {
15                unsafe {
16                    let v: ::ocaml::Pointer<Self> = v.as_pointer();
17                    v.drop_in_place();
18                }
19            }
20
21            extern "C" fn caml_pointer_compare(_: ::ocaml::Raw, _: ::ocaml::Raw) -> i32 {
22                // Always return equal. We can use this for sanity checks,
23                // anything else using this would be broken anyway.
24                0
25            }
26
27            pub fn new(x: $typ) -> Self {
28                Self(::std::sync::Arc::new(x))
29            }
30        }
31
32        ::ocaml::custom!($name {
33            finalize: $name::caml_pointer_finalize,
34            compare: $name::caml_pointer_compare,
35        });
36
37        unsafe impl<'a> ::ocaml::FromValue<'a> for $name {
38            fn from_value(value: ::ocaml::Value) -> Self {
39                let x: ::ocaml::Pointer<Self> = ::ocaml::FromValue::from_value(value);
40                Self(x.as_ref().0.clone())
41            }
42        }
43
44        //
45        // useful implementations
46        //
47
48        impl ::core::ops::Deref for $name {
49            type Target = ::std::sync::Arc<$typ>;
50
51            fn deref(&self) -> &Self::Target {
52                &self.0
53            }
54        }
55    };
56}