rustler
rustler copied to clipboard
Odd difference between ErlNifTermType and TermType returned by `Term.get_type()`
enif_get_type returns an enum value depending on the type of value a particular term is.
Rustler currently uses Term.get_type()
, which returns a TermType.
There is a difference in the types returned by these two approaches.
Under the hood, get_type
is implemented as a bunch of is_*
checks.
However, there are two downsides with this approach:
- They are slower;
- They do not disambiguate between integers and floats.
rustler_sys
does seem to know about the ErlNifTermType, but it doesn't seem to be used anywhere else in the code right now.
What would be the best way to improve this situation? I would be willing to contribute with a PR or two if someone can tell me which approach to take.
Note that enif_get_type
is rather recent (OTP 22). Rustler currently supports OTP 20.3 as well (at least according to the github actions). To implement that in a backwards-compatible way, Term.get_type()
could call into a feature-gated helper. For OTP >= 22, this would call into enif_get_type
and match
on the resulting enum, and for OTP < 22, the current logic would be used. See Term.map_from_arrays()
for an example on functions feature-gated to the NIF version.
The feature-gate mechanism uses build.rs
to determine the NIF version. The version check can be overridden with RUSTLER_NIF_VERSION
as well.
They do not disambiguate between integers and floats.
As long as we need to maintain backwards compatibility, this would still be the case.
TermType
and ErlNifTermType
don't match exactly. For example, TermType
has Number
, while ErlNifTermType
does not. Maybe we should have another function then to implement enif_get_type
? It is unfortunate that Term.get_type()
is already taken. So maybe we should not implement this for OTP < 22 at all, but instead disambiguate between the two?
See https://github.com/rusterlium/rustler/pull/538, which tackles this problem.
#538 has been merged and released, closing this.