defmodule Syntactic do @moduledoc """ Provides some syntactic sugars """ @doc """ Expands to a keyword list with keys as atoms of given vars. For example `keys([name, age])` expands to `[name: name, age: age]` Useful in matches: def full_name(keys(first_name, last_name)) do first_name <> " " <> last_name end full_name(first_name: "Alan", last_name: "Parsons") # => "Alan Parsons" """ defmacro keys(keys) when is_list(keys), do: keywords(keys) defmacro keys(a), do: keywords([a]) defmacro keys(a,b), do: keywords([a,b]) defmacro keys(a,b,c), do: keywords([a,b,c]) defmacro keys(a,b,c,d), do: keywords([a,b,c,d]) defmacro keys(a,b,c,d,e), do: keywords([a,b,c,d,e]) defp keywords(keys) do Enum.into keys, [], fn var = {name,_,_} -> {name, var} end end @doc """ Expands to a `Map` with keys as atoms of given vars. For example `map([name, age])` expands to `%{name: name, age: age}` Useful in matches: map(a, b) = %{a: 10, b: "Some Value"} """ defmacro map(keys) when is_list(keys), do: map_of(keys) defmacro map(a), do: map_of([a]) defmacro map(a,b), do: map_of([a,b]) defmacro map(a,b,c), do: map_of([a,b,c]) defmacro map(a,b,c,d), do: map_of([a,b,c,d]) defmacro map(a,b,c,d,e), do: map_of([a,b,c,d,e]) defp map_of(keys) do names = Enum.into keys, [], fn var = {name,_,_} -> {name, var} end quote do: %{unquote_splicing(names)} end @doc """ Expands to a `Map` with keys as strings of given vars. For example `maps([name, age])` expands to `%{"name" => name, "age" => age}` """ defmacro maps(keys) when is_list(keys), do: maps_of(keys) defmacro maps(a), do: maps_of([a]) defmacro maps(a,b), do: maps_of([a,b]) defmacro maps(a,b,c), do: maps_of([a,b,c]) defmacro maps(a,b,c,d), do: maps_of([a,b,c,d]) defmacro maps(a,b,c,d,e), do: maps_of([a,b,c,d,e]) defp maps_of(keys) do names = Enum.into keys, [], fn var = {name,_,_} -> {Atom.to_string(name), var} end quote do: %{unquote_splicing(names)} end end