Skip to content

Commit 14df9be

Browse files
authored
Issue #82 (#83)
* Erlang/Elixir nil/null issue addressed similar to jiffy use_nil approach. * README updated. * use_nil additionality implemented for unpack method.
1 parent 0dea2a4 commit 14df9be

File tree

6 files changed

+34
-0
lines changed

6 files changed

+34
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ bin binary() binary()
8888
str binary() string()
8989
```
9090

91+
### `{use_nil, boolean()}`
92+
93+
Handles Elixir `nil` as `null` Erlang atom. Default value is `false`.
94+
9195
### `{validate_string, boolean()}`
9296

9397
Only in unpacking, UTF-8 validation at unpacking from `str` type will

src/msgpack.erl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
{allow_atom, none|pack} |
5454
{known_atoms, [atom()]} |
5555
{unpack_str, as_binary|as_list|as_tagged_list} |
56+
{use_nil, boolean()} |
5657
{validate_string, boolean()} |
5758
{pack_str, from_binary|from_list|from_tagged_list|none} |
5859
{map_format, map|jiffy|jsx} |
@@ -171,6 +172,9 @@ parse_options([{known_atoms, Atoms}|T], Opt0) when is_list(Atoms) ->
171172
parse_options([{unpack_str, As}|T], Opt0) when As =:= as_binary orelse As =:= as_list orelse As =:= as_tagged_list ->
172173
parse_options(T, Opt0?OPTION{unpack_str=As});
173174

175+
parse_options([{use_nil, Bool}|T], Opt) when is_boolean(Bool) ->
176+
parse_options(T, Opt?OPTION{use_nil=Bool});
177+
174178
parse_options([{validate_string, Bool}|T], Opt) when is_boolean(Bool) ->
175179
parse_options(T, Opt?OPTION{validate_string=Bool});
176180

src/msgpack.hrl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
allow_atom = pack :: none | pack, %% allows atom when packing
3939
known_atoms = [] :: [atom()|binary()],
4040
unpack_str = as_list :: as_binary | as_list | as_tagged_list,
41+
use_nil = false :: boolean(),
4142
validate_string = false :: boolean(),
4243
pack_str = from_list :: from_binary | from_list | from_tagged_list | none,
4344
map_format = ?DEFAULT_MAP_FORMAT :: format_type(),

src/msgpack_packer.erl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ pack(F, _) when is_float(F) ->
3333
pack_double(F);
3434
pack(null, _Opt) ->
3535
<< 16#C0:8 >>;
36+
pack(nil, ?OPTION{use_nil = true}) ->
37+
<< 16#C0:8 >>;
3638
pack(false, _) ->
3739
<< 16#C2:8 >>;
3840
pack(true, _) ->

src/msgpack_unpacker.erl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
%% unpack them all
3030
-spec unpack_stream(Bin::binary(), ?OPTION{}) -> {msgpack:object(), binary()} | {error, any()} | no_return().
3131
%% ATOMS
32+
unpack_stream(<<16#C0, Rest/binary>>, ?OPTION{use_nil = true}) ->
33+
{nil, Rest};
3234
unpack_stream(<<16#C0, Rest/binary>>, _) ->
3335
{null, Rest};
3436
unpack_stream(<<16#C2, Rest/binary>>, _) ->

test/msgpack_tests.erl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,27 @@ unpack_str_validation_test_() ->
646646
[{spec,new},{unpack_str,from_list},{validate_string,true}]))]}
647647
].
648648

649+
pack_nil_test_() ->
650+
ElixirStyleNil = nil,
651+
NilConversionOpt = [{use_nil, true}],
652+
UseNilDefaultResult = msgpack:pack(ElixirStyleNil),
653+
UseNilTrueResult = msgpack:pack(ElixirStyleNil, NilConversionOpt),
654+
[{"use_nil default false",
655+
[?_assertEqual({ok, <<"nil">>}, msgpack:unpack(UseNilDefaultResult))]},
656+
{"use_nil explicitly set to true",
657+
[?_assertEqual({ok, null}, msgpack:unpack(UseNilTrueResult))]}
658+
].
659+
660+
unpack_nil_test_() ->
661+
NullPacked = <<16#C0>>,
662+
NilConversionOpt = [{use_nil, true}],
663+
UseNilDefaultResult = msgpack:unpack(NullPacked),
664+
UseNilTrueResult = msgpack:unpack(NullPacked, NilConversionOpt),
665+
[{"use_nil default false",
666+
[?_assertEqual({ok, null}, UseNilDefaultResult)]},
667+
{"use_nil explicitly set to true",
668+
[?_assertEqual({ok, nil}, UseNilTrueResult)]}
669+
].
649670

650671
float_unpacking_test_() ->
651672
%% float 32

0 commit comments

Comments
 (0)