Skip to content

Commit d7cc993

Browse files
committed
Start implementing generic wrapper types
1 parent 9522518 commit d7cc993

File tree

3 files changed

+69
-13
lines changed

3 files changed

+69
-13
lines changed

rustler/src/types/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
use crate::{Env, Error, NifResult, Term};
22

3+
#[macro_use]
4+
mod wrapper;
5+
pub(crate) use self::wrapper::wrapper;
6+
37
#[macro_use]
48
pub mod atom;
59
pub use crate::types::atom::Atom;

rustler/src/types/reference.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
use std::ops::Deref;
22

3-
use crate::{Decoder, Encoder, Env, Error, NifResult, Term};
3+
use crate::{Decoder, Encoder, Env, Error, NifResult, Term, TermType};
44

55
use crate::sys::enif_make_ref;
66

7-
/// Wrapper for BEAM reference terms.
8-
#[derive(PartialEq, Eq, Clone, Copy)]
9-
pub struct Reference<'a>(Term<'a>);
7+
wrapper!(Reference, TermType::Ref);
108

11-
impl 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-
}
9+
/// Wrapper for BEAM reference terms.
10+
// #[derive(PartialEq, Eq, Clone, Copy)]
11+
// pub struct Reference<'a>(Term<'a>);
12+
//
13+
// impl<'a> Reference<'a> {
14+
// /// Returns a representation of self in the given Env.
15+
// ///
16+
// /// If the term is already is in the provided env, it will be directly returned. Otherwise
17+
// /// the term will be copied over.
18+
// pub fn in_env<'b>(&self, env: Env<'b>) -> Reference<'b> {
19+
// Reference(self.0.in_env(env))
20+
// }
21+
// }
2022

2123
impl<'a> Deref for Reference<'a> {
2224
type Target = Term<'a>;

rustler/src/types/wrapper.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use crate::TermType;
2+
3+
struct WrapperError;
4+
5+
pub trait Wrapper<'a>: Sized {
6+
const WRAPPED_TYPE: TermType;
7+
8+
fn wrap<'b>(term: Term<'a>) -> Result<Self, WrapperError> {
9+
if term.get_type() == Self::WRAPPED_TYPE {
10+
unsafe { Ok(Self::wrap_unsafe(term)) }
11+
} else {
12+
Err(WrapperError)
13+
}
14+
}
15+
16+
fn unwrap(&self) -> Term<'a>;
17+
18+
unsafe fn wrap_unsafe(term: Term<'a>) -> Self;
19+
20+
/// Returns a representation of self in the given Env.
21+
///
22+
/// If the term is already is in the provided env, it will be directly returned. Otherwise
23+
/// the term will be copied over.
24+
fn in_env<'b>(&self, env: Env<'b>) -> impl Wrapper<'b, WRAPPED_TYPE = Self::WrappedType> {
25+
self.unwrap().in_env(env)
26+
}
27+
}
28+
29+
macro_rules! wrapper {
30+
($name:ident, $term_type:path) => {
31+
#[derive(PartialEq, Eq, Clone, Copy)]
32+
pub struct $name<'a>(Term<'a>);
33+
34+
impl<'a> $crate::types::wrapper::Wrapper<'a> for $name<'a> {
35+
const WrappedType: TermType = $term_type;
36+
37+
unsafe fn wrap_unsafe(term: Term<'a>) -> Self {
38+
$name(term)
39+
}
40+
41+
fn unwrap(&self) -> Term<'a> {
42+
self.0
43+
}
44+
}
45+
};
46+
}
47+
48+
pub(crate) use wrapper;
49+
50+
use crate::{Env, Term};

0 commit comments

Comments
 (0)