zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

exs_loader.ex (2948B)


      1 defmodule Credo.ExsLoader do
      2   @moduledoc false
      3 
      4   def parse(exs_string, filename, exec, safe \\ false)
      5 
      6   def parse(exs_string, filename, _exec, true) do
      7     case Code.string_to_quoted(exs_string, file: filename) do
      8       {:ok, ast} ->
      9         {:ok, process_exs(ast)}
     10 
     11       {:error, {line_meta, message, trigger}} when is_list(line_meta) ->
     12         {:error, {line_meta[:line], message, trigger}}
     13 
     14       {:error, value} ->
     15         {:error, value}
     16     end
     17   end
     18 
     19   def parse(exs_string, filename, exec, false) when is_atom(filename) do
     20     parse(exs_string, "mod:#{filename}", exec, false)
     21   end
     22 
     23   def parse(exs_string, filename, exec, false) when is_binary(filename) do
     24     {result, _binding} =
     25       Code.eval_string(exs_string, [exec: exec], file: to_string(filename) || "nofile")
     26 
     27     {:ok, result}
     28   rescue
     29     error ->
     30       case error do
     31         %SyntaxError{description: "syntax error before: " <> trigger, line: line_meta}
     32         when is_list(line_meta) ->
     33           {:error, {line_meta[:line], "syntax error before: ", trigger}}
     34 
     35         %SyntaxError{description: "syntax error before: " <> trigger, line: line_no} ->
     36           {:error, {line_no, "syntax error before: ", trigger}}
     37 
     38         error ->
     39           {:error, error}
     40       end
     41   end
     42 
     43   @doc false
     44   def parse_safe(exs_string) do
     45     case Code.string_to_quoted(exs_string) do
     46       {:ok, ast} ->
     47         process_exs(ast)
     48 
     49       _ ->
     50         %{}
     51     end
     52   end
     53 
     54   defp process_exs(v)
     55        when is_atom(v) or is_binary(v) or is_float(v) or is_integer(v),
     56        do: v
     57 
     58   defp process_exs(list) when is_list(list) do
     59     Enum.map(list, &process_exs/1)
     60   end
     61 
     62   defp process_exs({:sigil_w, _, [{:<<>>, _, [list_as_string]}, []]}) do
     63     String.split(list_as_string, ~r/\s+/)
     64   end
     65 
     66   # TODO: support regex modifiers
     67   defp process_exs({:sigil_r, _, [{:<<>>, _, [regex_as_string]}, []]}) do
     68     Regex.compile!(regex_as_string)
     69   end
     70 
     71   defp process_exs({:%{}, _meta, body}) do
     72     process_map(body, %{})
     73   end
     74 
     75   defp process_exs({:{}, _meta, body}) do
     76     process_tuple(body, {})
     77   end
     78 
     79   defp process_exs({:__aliases__, _meta, name_list}) do
     80     Module.safe_concat(name_list)
     81   end
     82 
     83   defp process_exs({{:__aliases__, _meta, name_list}, options}) do
     84     {Module.safe_concat(name_list), process_exs(options)}
     85   end
     86 
     87   defp process_exs({key, value}) when is_atom(key) or is_binary(key) do
     88     {process_exs(key), process_exs(value)}
     89   end
     90 
     91   defp process_tuple([], acc), do: acc
     92 
     93   defp process_tuple([head | tail], acc) do
     94     acc = process_tuple_item(head, acc)
     95     process_tuple(tail, acc)
     96   end
     97 
     98   defp process_tuple_item(value, acc) do
     99     Tuple.append(acc, process_exs(value))
    100   end
    101 
    102   defp process_map([], acc), do: acc
    103 
    104   defp process_map([head | tail], acc) do
    105     acc = process_map_item(head, acc)
    106     process_map(tail, acc)
    107   end
    108 
    109   defp process_map_item({key, value}, acc)
    110        when is_atom(key) or is_binary(key) do
    111     Map.put(acc, key, process_exs(value))
    112   end
    113 end