Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- defmodule Ldif do
- import NimbleParsec
- name= ascii_string([?a..?z, ?A..?Z, ?0..?9], min: 1)
- eol = ascii_char([?\n]) |> ignore()
- assigment =
- choice([
- string("::") |> replace(:base64),
- string(":") |> replace(:string)
- ])
- rest_value = ignore(string(" ")) |> ascii_string([32..255], min: 1) |> concat(eol)
- value = ascii_string([32..255], min: 1) |> concat(eol) |> repeat(rest_value)
- attribute = name |> concat(assigment) |> ignore(string(" ")) |> concat(value) |> tag(:attribute)
- attributes = repeat(lookahead_not(eol) |> concat(attribute)) |> concat(eol)
- defparsec :parseLdif,
- ignore(string("dn")) |> ignore(string(": ")) |> concat(value) |> tag(:dn)
- |> concat(attributes)
- def ldif(src) do
- Enum.reverse(parse_ldif(src, []))
- end
- defp parse_ldif("", xs), do: xs
- defp parse_ldif(src, xs) do
- with {:ok, result, rest, %{}, _, _} <- parseLdif(src) do
- record = Enum.reduce(result, %{}, fn
- {:dn, [dn]}, m -> Map.put(m, "dn", dn)
- {:attribute, attr}, m -> process_attribute(m, attr)
- end)
- parse_ldif(rest, [record | xs])
- end
- end
- defp update_map(map, key, value) do
- case Map.get(map, key, nil) do
- nil -> Map.put(map, key, value)
- xs when is_list(xs) -> Map.put(map, key, [value | xs])
- other -> Map.put(map, key, [value, other] )
- end
- end
- defp process_attribute(result, [key, :string, value]) do
- update_map(result, key, value)
- end
- defp process_attribute(result, [key, :base64, value]) do
- update_map(result, key, Base.decode64!(value) )
- end
- defp process_attribute(result, [key | [:base64 | xs]]) do
- update_map(result, key, Base.decode64!(Enum.join(xs, "")))
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement