Packages
drab
0.8.0
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.3
0.8.2
0.8.1
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.6.0-pre.1
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
Remote controlled frontend framework for Phoenix.
Current section
Files
Jump to
Current section
Files
lib/drab/live/assign.ex
defmodule Drab.Live.Assign do
@moduledoc false
@spec trim(term) :: term
@doc """
Reduces size of the assigns by shrinking @conn to include only the essential information
(by default it is .private.phoenix_endpoint only).
"""
def trim(%Plug.Conn{} = conn) do
filter = Drab.Config.get(:live_conn_pass_through)
trim(conn, filter)
end
def trim(other), do: other
def trim(struct, filter) do
filtered = filter(struct, filter)
merge(struct(struct.__struct__), filtered)
end
def filter(%Plug.Conn{} = conn) do
filter = Drab.Config.get(:live_conn_pass_through)
filter(conn, filter)
end
def filter(other), do: other
def filter(struct, filter) do
deep_filter_map(struct, filter)
end
def merge(%Plug.Conn{} = conn, map) do
merged = deep_merge_map(conn, map)
struct(%Plug.Conn{}, merged)
end
def merge(other), do: other
# all hails to @OvermindDL1 for this idea and the following functions
defp deep_filter_map(%{__struct__: _} = struct, map_filter) do
deep_filter_map(Map.from_struct(struct), map_filter)
end
defp deep_filter_map(original, map_filter) do
original
|> Enum.flat_map(fn {key, value} = set ->
case map_filter[key] do
true ->
[set]
%{} = map_filter when is_map(value) ->
value = deep_filter_map(value, map_filter)
if map_size(value) === 0, do: [], else: [{key, value}]
_ ->
[]
end
end)
|> Enum.into(%{})
end
defp deep_merge_map(%{__struct__: _} = struct, to_merge) do
deep_merge_map(Map.from_struct(struct), to_merge)
end
defp deep_merge_map(base, to_merge) do
to_merge
|> Enum.reduce(base, fn
{key, %{} = value}, base ->
sub = base[key] || %{}
sub = if is_map(sub), do: deep_merge_map(sub, value), else: sub
Map.put(base, key, sub)
{key, value}, base ->
Map.put(base, key, value)
end)
end
end