aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dmarc/parser.ex
diff options
context:
space:
mode:
authorGravatar Joe Banks <[email protected]>2025-05-28 22:04:52 +0100
committerGravatar Joe Banks <[email protected]>2025-05-28 22:04:52 +0100
commitfd1d5ac093e54992bf86155f847a10b9557d5594 (patch)
tree570a76837d91a7f00123ea8e88c72e17ccb619a1 /lib/dmarc/parser.ex
parentAdd PSL GenServer (diff)
Add leex and yecc files & Elixir interface for DMARC parse
Diffstat (limited to 'lib/dmarc/parser.ex')
-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