diff --git a/c_src/fxml_stream.c b/c_src/fxml_stream.c
index f75e203..e9b5677 100644
--- a/c_src/fxml_stream.c
+++ b/c_src/fxml_stream.c
@@ -862,10 +862,25 @@ static ERL_NIF_TERM parse_element_nif(ErlNifEnv* env, int argc,
{
ERL_NIF_TERM el;
ErlNifBinary bin;
+ int use_maps = 0;
- if (argc != 1)
+ if (argc != 1 && argc != 2)
return enif_make_badarg(env);
+ if (argc == 2) {
+ if (!enif_is_list(env, argv[1]))
+ return enif_make_badarg(env);
+
+ ERL_NIF_TERM head, tail = argv[1];
+ while (enif_get_list_cell(env, tail, &head, &tail)) {
+ char buf[16];
+ if (enif_get_atom(env, head, buf, sizeof(buf), ERL_NIF_LATIN1)) {
+ if (strcmp("use_maps", buf) == 0)
+ use_maps = 1;
+ }
+ }
+ }
+
if (!enif_inspect_binary(env, argv[0], &bin))
return enif_make_badarg(env);
@@ -874,6 +889,7 @@ static ERL_NIF_TERM parse_element_nif(ErlNifEnv* env, int argc,
return enif_make_badarg(env);
state->send_env = env;
+ state->use_maps = use_maps;
xmlel_stack_t *xmlel = enif_alloc(sizeof(xmlel_stack_t));
if (!xmlel) {
@@ -1060,6 +1076,7 @@ static ErlNifFunc nif_funcs[] =
{"new", 3, new_nif},
{"parse", 2, parse_nif},
{"parse_element", 1, parse_element_nif},
+ {"parse_element", 2, parse_element_nif},
{"reset", 1, reset_nif},
{"close", 1, close_nif},
{"change_callback_pid", 2, change_callback_pid_nif}
diff --git a/src/fxml_stream.erl b/src/fxml_stream.erl
index 23f3b1d..046fb47 100644
--- a/src/fxml_stream.erl
+++ b/src/fxml_stream.erl
@@ -30,7 +30,7 @@
-on_load(init/0).
-export([new/1, new/2, new/3, parse/2, close/1, reset/1,
- change_callback_pid/2, parse_element/1]).
+ change_callback_pid/2, parse_element/1, parse_element/2]).
-export([load_nif/0, load_nif/1]).
@@ -113,3 +113,9 @@ close(_State) ->
parse_element(_Str) ->
erlang:nif_error(nif_not_loaded).
+
+-spec parse_element(binary(), [use_maps]) -> xmlel() |
+ {error, atom()} |
+ {error, {integer(), binary()}}.
+parse_element(_Str, _Options) ->
+ erlang:nif_error(nif_not_loaded).
diff --git a/test/elixir/fast_xml_test.exs b/test/elixir/fast_xml_test.exs
index 6ee1cf8..62081ed 100644
--- a/test/elixir/fast_xml_test.exs
+++ b/test/elixir/fast_xml_test.exs
@@ -15,19 +15,22 @@
defmodule FastXMLTest do
use ExUnit.Case
- # TODO: we should be able to pass :use_maps option to :fxml_stream.parse_element/2
+ test "Parse element can return Elixir structs" do
+ assert %FastXML.El{name: "root"} == :fxml_stream.parse_element("", [:use_maps])
+ end
test "Stream parser can return Elixir structs" do
- s1 = :fxml_stream.new(self, :infinity, [:no_gen_server, :use_maps])
- s2 = :fxml_stream.parse(s1, "")
- assert receive_stanza == %FastXML.StreamStart{name: "root"}
- s3 = :fxml_stream.parse(s2, "content cdata")
- assert receive_stanza == %FastXML.El{name: "xmlelement", children: ["content cdata"]}
- s4 = :fxml_stream.parse(s3, "content cdata")
- assert receive_stanza == %FastXML.El{name: "xmlelement", children: ["content cdata"]}
- s5 = :fxml_stream.parse(s4, "")
- assert receive_stanza == %FastXML.StreamEnd{name: "root"}
- :fxml_stream.close(s5)
+ :fxml_stream.new(self(), :infinity, [:no_gen_server, :use_maps])
+ |> :fxml_stream.parse("")
+ |> :fxml_stream.parse("content cdata")
+ |> :fxml_stream.parse("content cdata")
+ |> :fxml_stream.parse("")
+ |> :fxml_stream.close()
+
+ assert receive_stanza() == %FastXML.StreamStart{name: "root"}
+ assert receive_stanza() == %FastXML.El{name: "xmlelement", children: ["content cdata"]}
+ assert receive_stanza() == %FastXML.El{name: "xmlelement", children: [%FastXML.El{name: "empty"}, %FastXML.El{name: "subelement", attrs: %{"attribute" => "true"}, children: ["content cdata"]}]}
+ assert receive_stanza() == %FastXML.StreamEnd{name: "root"}
end
test "Size of parsed stanza can be limited" do
@@ -49,7 +52,7 @@ defmodule FastXMLTest do
# TODO test mismatched tags
- defp receive_stanza do
+ defp receive_stanza() do
receive do
result ->
result
diff --git a/test/fxml_test.erl b/test/fxml_test.erl
index b2f3f55..6bbfaff 100644
--- a/test/fxml_test.erl
+++ b/test/fxml_test.erl
@@ -121,6 +121,9 @@ tag_with_tags_test() ->
{xmlcdata, <<"cdata2">>}]},
fxml_stream:parse_element(<<"cdata1cdata2">>)).
+use_maps_test() ->
+ ?assertEqual(#{'__struct__' => 'Elixir.FastXML.El', name => <<"root">>, attrs => #{}, children => []}, fxml_stream:parse_element(<<"">>, [use_maps])).
+
receiver(Acc) ->
receive
{'$gen_event', Msg} ->