aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/dmarc/parser.ex49
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/dmarc/parser.ex b/lib/dmarc/parser.ex
new file mode 100644
index 0000000..e4fd29b
--- /dev/null
+++ b/lib/dmarc/parser.ex
@@ -0,0 +1,49 @@
+defmodule Lithium.DMARC.Parser do
+ @moduledoc """
+ A wrapper around the `:dmarc_parser` yecc and leex parser.
+
+ This module is responsible for parsing DMARC records and returning a
+ map of the parsed values. It is then up to the `Lithium.DMARC.Policy`
+ module to validate and process these values.
+ """
+
+ def parse_policy(record) do
+ case :dmarc_lexer.string(String.to_charlist(record)) do
+ {:ok, tokens, _} ->
+ case :dmarc_parser.parse(tokens) do
+ {:ok, parsed} ->
+ {:ok, keyword_to_string_map(parsed)}
+
+ {:error, reason} ->
+ {:error, reason}
+
+ {:error, reason, _} ->
+ {:error, reason}
+ end
+
+ {:error, reason} ->
+ {:error, reason}
+
+ {:error, reason, _} ->
+ {:error, reason}
+ end
+ end
+
+ defp keyword_to_string_map(keyword_list) do
+ keyword_list
+ |> Enum.map(fn {k, v} ->
+ {k, convert_value(v)}
+ end)
+ |> Map.new()
+ end
+
+ defp convert_value(value) when is_list(value) and is_integer(hd(value)) do
+ to_string(value)
+ end
+
+ defp convert_value(value) when is_list(value) do
+ Enum.map(value, &convert_value/1)
+ end
+
+ defp convert_value(value), do: value
+end