zf

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

sigil.ex (1953B)


      1 defmodule Jason.Sigil do
      2   @doc ~S"""
      3   Handles the sigil `~j` for JSON strings.
      4 
      5   Calls `Jason.decode!/2` with modifiers mapped to options.
      6 
      7   Given a string literal without interpolations, decodes the
      8   string at compile-time.
      9 
     10   ## Modifiers
     11 
     12   See `Jason.decode/2` for detailed descriptions.
     13 
     14     * `a` - equivalent to `{:keys, :atoms}` option
     15     * `A` - equivalent to `{:keys, :atoms!}` option
     16     * `r` - equivalent to `{:strings, :reference}` option
     17     * `c` - equivalent to `{:strings, :copy}` option
     18 
     19   ## Examples
     20 
     21       iex> ~j"0"
     22       0
     23 
     24       iex> ~j"[1, 2, 3]"
     25       [1, 2, 3]
     26 
     27       iex> ~j'"string"'r
     28       "string"
     29 
     30       iex> ~j"{}"
     31       %{}
     32 
     33       iex> ~j'{"atom": "value"}'a
     34       %{atom: "value"}
     35 
     36       iex> ~j'{"#{:j}": #{'"j"'}}'A
     37       %{j: "j"}
     38 
     39   """
     40   defmacro sigil_j(term, modifiers)
     41 
     42   defmacro sigil_j({:<<>>, _meta, [string]}, modifiers) when is_binary(string) do
     43     Macro.escape(Jason.decode!(string, mods_to_opts(modifiers)))
     44   end
     45 
     46   defmacro sigil_j(term, modifiers) do
     47     quote(do: Jason.decode!(unquote(term), unquote(mods_to_opts(modifiers))))
     48   end
     49 
     50   @doc ~S"""
     51   Handles the sigil `~J` for raw JSON strings.
     52 
     53   Decodes a raw string ignoring Elixir interpolations and
     54   escape characters at compile-time.
     55 
     56   ## Examples
     57 
     58       iex> ~J'"#{string}"'
     59       "\#{string}"
     60 
     61       iex> ~J'"\u0078\\y"'
     62       "x\\y"
     63 
     64       iex> ~J'{"#{key}": "#{}"}'a
     65       %{"\#{key}": "\#{}"}
     66   """
     67   defmacro sigil_J(term, modifiers)
     68 
     69   defmacro sigil_J({:<<>>, _meta, [string]}, modifiers) when is_binary(string) do
     70     Macro.escape(Jason.decode!(string, mods_to_opts(modifiers)))
     71   end
     72 
     73   @spec mods_to_opts(charlist) :: [Jason.decode_opt()]
     74   defp mods_to_opts(modifiers) do
     75     modifiers
     76     |> Enum.map(fn
     77       ?a -> {:keys, :atoms}
     78       ?A -> {:keys, :atoms!}
     79       ?r -> {:strings, :reference}
     80       ?c -> {:strings, :copy}
     81       m -> raise ArgumentError, "unknown sigil modifier #{<<?", m, ?">>}"
     82     end)
     83   end
     84 end