rustler/types/
reference.rs

1use std::ops::Deref;
2
3use crate::{Decoder, Encoder, Env, Error, NifResult, Term};
4
5use crate::sys::enif_make_ref;
6
7/// Wrapper for BEAM reference terms.
8#[derive(PartialEq, Eq, Clone, Copy)]
9pub struct Reference<'a>(Term<'a>);
10
11impl Reference<'_> {
12    /// Returns a representation of self in the given Env.
13    ///
14    /// If the term is already is in the provided env, it will be directly returned. Otherwise
15    /// the term will be copied over.
16    pub fn in_env<'b>(&self, env: Env<'b>) -> Reference<'b> {
17        Reference(self.0.in_env(env))
18    }
19}
20
21impl<'a> Deref for Reference<'a> {
22    type Target = Term<'a>;
23
24    fn deref(&self) -> &Self::Target {
25        &self.0
26    }
27}
28
29impl<'a> From<Reference<'a>> for Term<'a> {
30    fn from(term: Reference<'a>) -> Self {
31        term.0
32    }
33}
34
35impl<'a> TryFrom<Term<'a>> for Reference<'a> {
36    type Error = Error;
37
38    fn try_from(term: Term<'a>) -> Result<Self, Self::Error> {
39        if term.is_ref() {
40            Ok(Reference(term))
41        } else {
42            Err(Error::BadArg)
43        }
44    }
45}
46
47impl<'a> Decoder<'a> for Reference<'a> {
48    fn decode(term: Term<'a>) -> NifResult<Self> {
49        term.try_into()
50    }
51}
52
53impl Encoder for Reference<'_> {
54    fn encode<'b>(&self, env: Env<'b>) -> Term<'b> {
55        self.0.encode(env)
56    }
57}
58
59impl<'a> Env<'a> {
60    /// Create a new reference in this environment
61    pub fn make_ref(self) -> Reference<'a> {
62        unsafe { Reference(Term::new(self, enif_make_ref(self.as_c_arg()))) }
63    }
64}