1
1
import std/ macros
2
2
import std/ typetraits
3
3
import std/ tables
4
- import std/ hashes
5
4
import bindings/ erl_nif
6
5
7
6
import std/ options
@@ -11,17 +10,10 @@ using
11
10
env: ptr ErlNifEnv
12
11
term: ErlNifTerm
13
12
14
- type
15
- ErlAtom * = object
16
- val* : string
17
- ErlCharlist * = seq [char ]
18
- ErlBinary * = ErlNifBinary
19
-
20
- const AtomOk * = ErlAtom (val: " ok" )
21
- const AtomError * = ErlAtom (val: " error" )
22
- const AtomTrue * = ErlAtom (val: " true" )
23
- const AtomFalse * = ErlAtom (val: " false" )
24
- const AtomMapEncodeException = ErlAtom (val: " nimler: fail to encode map" )
13
+ const AtomOk * = ErlAtom (" ok" )
14
+ const AtomError * = ErlAtom (" error" )
15
+ const AtomTrue * = ErlAtom (" true" )
16
+ const AtomFalse * = ErlAtom (" false" )
25
17
26
18
macro generic_params (T: typedesc ): untyped =
27
19
result = newNimNode (nnkTupleConstr)
@@ -43,10 +35,6 @@ macro generic_params(T: typedesc): untyped =
43
35
else :
44
36
error " wrong kind: " & $ impl.kind
45
37
46
- func hash * (a: ErlAtom ): Hash {.inline .} =
47
- result = a.val.hash
48
- result = !$ result
49
-
50
38
# int
51
39
func from_term * (env; term; T: typedesc [int ]): Option [T] {.inline .} =
52
40
var res: int
@@ -115,27 +103,27 @@ func from_term*(env; term; T: typedesc[ErlAtom]): Option[T] {.inline.} =
115
103
var atom_len: cuint
116
104
if enif_get_atom_length (env, term, addr (atom_len), ERL_NIF_LATIN1 ):
117
105
let buf_len = atom_len + 1
118
- var atom = ErlAtom (val: newString (atom_len) )
119
- if enif_get_atom (env, term, addr (atom.val [0 ]), buf_len, ERL_NIF_LATIN1 ) == cint (buf_len):
120
- result = some (atom)
106
+ var atom = newString (atom_len)
107
+ if enif_get_atom (env, term, addr (atom[0 ]), buf_len, ERL_NIF_LATIN1 ) == cint (buf_len):
108
+ result = some (ErlAtom ( atom) )
121
109
122
110
func to_term * (env; V: ErlAtom ): ErlNifTerm {.inline .} =
123
111
var res: ErlNifTerm
124
- if enif_make_existing_atom_len (env, V.val , len (V.val ).csize_t , addr (res)):
112
+ if enif_make_existing_atom_len (env, V.cstring , len (V).csize_t , addr (res)):
125
113
result = res
126
114
else :
127
- result = enif_make_atom_len (env, V.val , len (V.val ).csize_t )
115
+ result = enif_make_atom_len (env, V.cstring , len (V).csize_t )
128
116
129
117
# charlist
130
- func from_term * (env; term; T: typedesc [ErlCharlist ]): Option [T] {.inline .} =
118
+ func from_term * (env; term; T: typedesc [seq [ char ] ]): Option [T] {.inline .} =
131
119
var string_len: cuint
132
120
if enif_get_list_length (env, term, addr (string_len)):
133
121
let buf_len = string_len + 1
134
122
var string_buf = newSeq [char ](string_len)
135
123
if enif_get_string (env, term, addr (string_buf[0 ]), buf_len, ERL_NIF_LATIN1 ) == cint (buf_len):
136
124
result = some (string_buf)
137
125
138
- func to_term * (env; V: ErlCharlist ): ErlNifTerm {.inline .} =
126
+ func to_term * (env; V: seq [ char ] ): ErlNifTerm {.inline .} =
139
127
enif_make_string_len (env, V, ERL_NIF_LATIN1 )
140
128
141
129
# string
@@ -155,16 +143,21 @@ func to_term*(env; V: string): ErlNifTerm {.inline.} =
155
143
result = term
156
144
157
145
# binary
158
- func from_term * (env; term; T: typedesc [ErlBinary ]): Option [T] {.inline .} =
159
- var bin: ErlNifBinary
160
- if enif_inspect_binary (env, term, addr (bin)):
146
+ func from_term * (env; term; T: typedesc [seq [byte ]]): Option [T] {.inline .} =
147
+ var erl_bin: ErlNifBinary
148
+ if enif_inspect_binary (env, term, addr (erl_bin)):
149
+ var bin = newSeq [byte ](erl_bin.size)
150
+ copyMem (addr (bin[0 ]), erl_bin.data, erl_bin.size)
161
151
result = some (bin)
162
152
163
- func to_term * (env; V: ErlBinary ): ErlNifTerm {.inline .} =
164
- enif_make_binary (env, unsafeAddr (V))
153
+ func to_term * (env; V: seq [byte ]): ErlNifTerm {.inline .} =
154
+ var term: ErlNifTerm
155
+ var bin = cast [ptr byte ](enif_make_new_binary (env, len (V).csize_t , term.addr ))
156
+ copyMem (bin, unsafeAddr (V[0 ]), len (V))
157
+ result = term
165
158
166
159
# list
167
- func from_term * (env; term; T: typedesc [seq ]): Option [T] {. inline .} =
160
+ func from_term * (env; term; T: typedesc [seq ]): Option [T] =
168
161
if not enif_is_list (env, term):
169
162
return none (T)
170
163
var res: T
@@ -179,7 +172,7 @@ func from_term*(env; term; T: typedesc[seq]): Option[T] {.inline.} =
179
172
cursor = tail
180
173
return some (res)
181
174
182
- func to_term * (env; V: seq ): ErlNifTerm {. inline .} =
175
+ func to_term * (env; V: seq ): ErlNifTerm =
183
176
var v = newSeqOfCap [ErlNifTerm ](V.len)
184
177
for el in V:
185
178
v.add (env.to_term (el))
@@ -204,19 +197,17 @@ func from_term*(env; term; T: typedesc[tuple]): Option[T] =
204
197
return some (res)
205
198
206
199
macro to_term * (env: typed ; V: tuple ): untyped =
207
- case V.kind:
208
- of nnkSym:
209
- let tup_len = V.getTypeImpl ().len
210
- result = newCall (" enif_make_tuple" , env, newLit (tup_len))
211
- for i in 0 ..< tup_len:
212
- let v = quote do : `V`[`i`]
213
- result .add (newCall (" to_term" , env, v))
214
- of nnkTupleConstr:
215
- result = quote do :
216
- let erl_tup = `V`
217
- to_term (env, erl_tup)
218
- else :
219
- error " wrong kind: " & $ V.kind
200
+ expectKind (V, {nnkSym, nnkTupleConstr})
201
+ if V.kind == nnkSym:
202
+ let tup_len = V.getTypeImpl ().len
203
+ result = newCall (" enif_make_tuple" , env, newLit (tup_len))
204
+ for i in 0 ..< tup_len:
205
+ let v = quote do : `V`[`i`]
206
+ result .add (newCall (" to_term" , env, v))
207
+ elif V.kind == nnkTupleConstr:
208
+ result = quote do :
209
+ let erl_tup = `V`
210
+ to_term (env, erl_tup)
220
211
221
212
# map/table
222
213
func from_term * (env; term; T: typedesc [Table ]): Option [T] =
@@ -243,10 +234,10 @@ func to_term*(env; V: Table): ErlNifTerm =
243
234
for k, v in V:
244
235
keys.add (env.to_term (k))
245
236
vals.add (env.to_term (v))
246
- var map : ErlNifTerm
247
- if not enif_make_map_from_arrays (env, addr (keys[0 ]), addr (vals[0 ]), cuint (keys.len), addr (map )):
248
- return enif_raise_exception (env, env.to_term (AtomMapEncodeException ))
249
- return map
237
+ var res : ErlNifTerm
238
+ if not enif_make_map_from_arrays (env, addr (keys[0 ]), addr (vals[0 ]), cuint (keys.len), addr (res )):
239
+ return enif_raise_exception (env, env.to_term (ErlAtom ( " fail to encode map " ) ))
240
+ return res
250
241
251
242
# result
252
243
template result_tuple * (env; res_type: ErlnifTerm ; terms: varargs [ErlNifTerm ]): untyped =
@@ -256,3 +247,4 @@ template ok*(env; terms: varargs[ErlNifTerm]): untyped =
256
247
result_tuple (env, env.to_term (AtomOk ), terms)
257
248
258
249
template error * (env; terms: varargs [ErlNifTerm ]): untyped =
250
+ result_tuple (env, env.to_term (AtomError ), terms)
0 commit comments