Skip to main content

otter/types/terms/
reference.rs

1//! [`Reference`] — unique Erlang references (`make_ref`), the canonical
2//! one-shot token for tagging messages and replies.
3
4use core::marker::PhantomData;
5
6use crate::types::sealed::Sealed;
7use crate::types::{Env, Invariant, RawTerm, Term};
8
9/// An Erlang reference — a VM-unique token (`enif_make_ref`), commonly used to
10/// tag a request so its reply can be matched.
11#[derive(Clone, Copy)]
12pub struct Reference<'id> {
13    raw_term: RawTerm,
14    _id: Invariant<'id>,
15}
16
17impl<'id> Reference<'id> {
18    #[crate::raw]
19    pub(crate) fn from_raw(raw_term: RawTerm) -> Self {
20        Self { raw_term, _id: PhantomData }
21    }
22
23    /// Create a new unique reference (`enif_make_ref`).
24    pub fn new(env: impl Env<'id>) -> Self {
25        let raw_term = unsafe { enif_ffi::make_ref(env.raw_env()) };
26        Reference { raw_term, _id: PhantomData }
27    }
28
29    /// Returns `true` if `term` is a reference (`enif_is_ref`).
30    pub fn is_ref(env: impl Env<'id>, term: impl Term<'id>) -> bool {
31        unsafe { enif_ffi::is_ref(env.raw_env(), term.raw_term()) != 0 }
32    }
33}
34
35impl<'id> Sealed for Reference<'id> {}
36
37impl<'id> Term<'id> for Reference<'id> {
38    fn raw_term(self) -> RawTerm {
39        self.raw_term
40    }
41}
42
43impl PartialEq for Reference<'_> {
44    fn eq(&self, other: &Self) -> bool {
45        unsafe { enif_ffi::is_identical(self.raw_term, other.raw_term) != 0 }
46    }
47}
48
49impl Eq for Reference<'_> {}
50
51impl PartialOrd for Reference<'_> {
52    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
53        Some(self.cmp(other))
54    }
55}
56
57impl Ord for Reference<'_> {
58    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
59        let c = unsafe { enif_ffi::compare(self.raw_term, other.raw_term) };
60        c.cmp(&0)
61    }
62}
63
64impl std::fmt::Debug for Reference<'_> {
65    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66        write!(f, "Reference")
67    }
68}