Glad you joined here! 
@sasajuric Yes! I had my head fixated on macros from my initial misframing of the problem, and I didn’t realize that you could just use a function in a module attribute. This would be the “simple” aspect I think that @eugene is referring to. I also had to adjust the map filtering, since the Enum.member?
call doesn’t work for the nested maps.
defmodule MapConstants.Helper do
def gen_map(src, passing_values) when is_map(src) do
src
|> Enum.reduce(%{}, fn({key, value}, acc) ->
cond do
is_atom(value) and value in passing_values ->
Map.put(acc, key, value)
is_atom(value) ->
acc
is_map(value) ->
nested_map = gen_map(value, passing_values)
if map_size(nested_map) > 0 do
Map.put(acc, key, nested_map)
else
acc
end
end
end)
end
end
defmodule MapConstants do
import MapConstants.Helper
@mapping_fields %{
"id" => :id,
"user" => %{
"name" => :user_name,
"email" => :user_email
},
"project" => %{
"name" => :project_name
},
"created_at" => :inserted_at
}
@filterable_values [:id, :user_email, :inserted_at]
@insertable_values [:user_email, :user_name, :project_name]
@filterable_mapping_fields gen_map(@mapping_fields, @filterable_values)
@insertable_mapping_fields gen_map(@mapping_fields, @insertable_values)
def get_mapping_fields(:all), do: @mapping_fields
def get_mapping_fields(:filterable), do: @filterable_mapping_fields
def get_mapping_fields(:insertable), do: @insertable_mapping_fields
end
and here is the corresponding disassembly
{:function, :get_mapping_fields, 1, 7,
[{:line, 1}, {:label, 6},
{:func_info, {:atom, MapConstants}, {:atom, :get_mapping_fields}, 1},
{:label, 7}, {:test, :is_atom, {:f, 6}, [x: 0]},
{:select_val, {:x, 0}, {:f, 6},
{:list,
[atom: :all, f: 8, atom: :filterable, f: 9, atom: :insertable, f: 10]}},
{:label, 8},
{:move,
{:literal,
%{"created_at" => :inserted_at, "id" => :id,
"project" => %{"name" => :project_name},
"user" => %{"email" => :user_email, "name" => :user_name}}}, {:x, 0}},
:return, {:label, 9},
{:move,
{:literal,
%{"created_at" => :inserted_at, "id" => :id,
"user" => %{"email" => :user_email}}}, {:x, 0}}, :return, {:label, 10},
{:move,
{:literal,
%{"project" => %{"name" => :project_name},
"user" => %{"email" => :user_email, "name" => :user_name}}}, {:x, 0}},
:return]},
And if you’re interested, I’ve uploaded a concept app for it, and here the test file.