@@ -9,32 +9,27 @@ impl From<WrapperError> for crate::Error {
9
9
}
10
10
}
11
11
12
- pub trait Wrapper < ' a > : Sized {
12
+ pub trait Wrapper : Sized {
13
13
const WRAPPED_TYPE : TermType ;
14
14
15
- unsafe fn wrap_ptr_unchecked ( env : Env < ' a > , ptr : ERL_NIF_TERM ) -> Self {
15
+ unsafe fn wrap_ptr_unchecked < ' a > ( env : Env < ' a > , ptr : ERL_NIF_TERM ) -> Self {
16
16
Self :: wrap_unchecked ( Term :: new ( env, ptr) )
17
17
}
18
18
19
- fn wrap ( term : Term < ' a > ) -> Result < Self , WrapperError > {
19
+ fn wrap < ' a > ( term : Term < ' a > ) -> Result < Self , WrapperError > {
20
20
if term. get_type ( ) == Self :: WRAPPED_TYPE {
21
21
unsafe { Ok ( Self :: wrap_unchecked ( term) ) }
22
22
} else {
23
23
Err ( WrapperError )
24
24
}
25
25
}
26
26
27
- fn unwrap ( & self ) -> Term < ' a > ;
28
- unsafe fn wrap_unchecked ( term : Term < ' a > ) -> Self ;
29
- }
27
+ fn unwrap < ' a > ( & self , env : Env < ' a > ) -> Term < ' a > ;
30
28
31
- impl < ' a , T > From < T > for Term < ' a >
32
- where
33
- T : Wrapper < ' a > ,
34
- {
35
- fn from ( term : T ) -> Self {
36
- term. unwrap ( )
29
+ unsafe fn unwrap_ptr_unchecked < ' a > ( & self , env : Env < ' a > ) -> ERL_NIF_TERM {
30
+ self . unwrap ( env) . as_c_arg ( )
37
31
}
32
+ unsafe fn wrap_unchecked < ' a > ( term : Term < ' a > ) -> Self ;
38
33
}
39
34
40
35
macro_rules! wrapper {
@@ -54,20 +49,20 @@ macro_rules! wrapper {
54
49
/// If the term is already is in the provided env, it will be directly returned.
55
50
/// Otherwise the term will be copied over.
56
51
pub fn in_env<' b>( & self , env: Env <' b>) -> $name<' b> {
57
- let term = self . unwrap( ) . in_env ( env) ;
52
+ let term = self . unwrap( env) ;
58
53
unsafe { $name:: wrap_unchecked( term) }
59
54
}
60
55
}
61
56
62
- impl <' a> Wrapper < ' a> for $name<' a> {
57
+ impl <' a> Wrapper for $name<' a> {
63
58
const WRAPPED_TYPE : $crate:: TermType = $term_type;
64
59
65
- unsafe fn wrap_unchecked( term: Term <' a >) -> Self {
60
+ unsafe fn wrap_unchecked< ' b> ( term: Term <' b >) -> Self {
66
61
$name( term)
67
62
}
68
63
69
- fn unwrap( & self ) -> Term <' a > {
70
- self . 0
64
+ fn unwrap< ' b> ( & self , env : Env < ' b> ) -> Term <' b > {
65
+ self . 0 . in_env ( env )
71
66
}
72
67
}
73
68
@@ -97,7 +92,77 @@ macro_rules! wrapper {
97
92
98
93
impl <' a> $crate:: Encoder for $name<' a> {
99
94
fn encode<' b>( & self , env: $crate:: Env <' b>) -> Term <' b> {
100
- self . 0 . encode( env)
95
+ self . unwrap( ) . encode( env)
96
+ }
97
+ }
98
+
99
+ // impl<'a> std::hash::Hash for $name<'a> {
100
+ // fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
101
+ // self.0.hash(state);
102
+ // }
103
+ // }
104
+ //
105
+ impl <' a> std:: fmt:: Debug for $name<' a> {
106
+ fn fmt( & self , f: & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
107
+ self . 0 . fmt( f)
108
+ }
109
+ }
110
+ } ;
111
+ }
112
+
113
+ macro_rules! wrapper_impls {
114
+ ( $name: ident, $term_type: path) => {
115
+ impl <' a> $name<' a> {
116
+ /// Returns a representation of self in the given Env.
117
+ ///
118
+ /// If the term is already is in the provided env, it will be directly returned.
119
+ /// Otherwise the term will be copied over.
120
+ pub fn in_env<' b>( & self , env: Env <' b>) -> $name<' b> {
121
+ use $crate:: wrapped_types:: Wrapper ;
122
+ let term = self . unwrap( ) . in_env( env) ;
123
+ unsafe { $name:: wrap_unchecked( term) }
124
+ }
125
+ }
126
+
127
+ impl <' a> std:: ops:: Deref for $name<' a> {
128
+ type Target = Term <' a>;
129
+
130
+ fn deref( & self ) -> & Self :: Target {
131
+ & self . unwrap( )
132
+ }
133
+ }
134
+
135
+ impl <' a> TryFrom <Term <' a>> for $name<' a> {
136
+ type Error = $crate:: Error ;
137
+
138
+ fn try_from( term: Term <' a>) -> Result <Self , Self :: Error > {
139
+ use $crate:: wrapped_types:: Wrapper ;
140
+ Self :: wrap( term) . or( Err ( $crate:: Error :: BadArg ) )
141
+ }
142
+ }
143
+
144
+ impl <' a> $crate:: Decoder <' a> for $name<' a> {
145
+ fn decode( term: Term <' a>) -> $crate:: NifResult <Self > {
146
+ use $crate:: wrapped_types:: Wrapper ;
147
+ Self :: wrap( term) . or( Err ( $crate:: Error :: BadArg ) )
148
+ }
149
+ }
150
+
151
+ impl <' a> $crate:: Encoder for $name<' a> {
152
+ fn encode<' b>( & self , env: $crate:: Env <' b>) -> Term <' b> {
153
+ self . unwrap( ) . encode( env)
154
+ }
155
+ }
156
+
157
+ impl <' a> std:: hash:: Hash for $name<' a> {
158
+ fn hash<H : std:: hash:: Hasher >( & self , state: & mut H ) {
159
+ self . unwrap( ) . hash( state) ;
160
+ }
161
+ }
162
+
163
+ impl <' a> std:: fmt:: Debug for $name<' a> {
164
+ fn fmt( & self , f: & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
165
+ self . unwrap( ) . fmt( f)
101
166
}
102
167
}
103
168
} ;
0 commit comments