Download extra/lib/plausible/audit/encoder.ex from Leon4gr45/analytics: direct link, hf CLI and curl.
- Browser
- Download file 3.35 kB
-
https://huggingface.co/spaces/Leon4gr45/analytics/resolve/main/extra/lib/plausible/audit/encoder.ex
- Command line
-
hf download hf://spaces/Leon4gr45/analytics/extra/lib/plausible/audit/encoder.ex
-
curl -L -o encoder.ex https://huggingface.co/spaces/Leon4gr45/analytics/resolve/main/extra/lib/plausible/audit/encoder.ex
3.35 kB
| defmodule Plausible.Audit.EncoderError do | |
| defexception [:message] | |
| end | |
| defprotocol Plausible.Audit.Encoder do | |
| def encode(x) | |
| def encode(x, opts) | |
| end | |
| defimpl Plausible.Audit.Encoder, for: Ecto.Changeset do | |
| def encode(changeset, opts \\ []) do | |
| changes = | |
| Enum.reduce(changeset.changes, %{}, fn {k, v}, acc -> | |
| Map.put(acc, k, Plausible.Audit.Encoder.encode(v, opts)) | |
| end) | |
| data = Plausible.Audit.Encoder.encode(changeset.data, opts) | |
| case {map_size(data), map_size(changes)} do | |
| {n, 0} when n > 0 -> | |
| data | |
| {0, n} when n > 0 -> | |
| changes | |
| {0, 0} -> | |
| %{} | |
| _ -> | |
| %{before: data, after: changes} | |
| end | |
| end | |
| end | |
| defimpl Plausible.Audit.Encoder, for: Map do | |
| def encode(x, opts \\ []) do | |
| {allow_not_loaded, data} = Map.pop(x, :__allow_not_loaded__) | |
| raise_on_not_loaded? = Keyword.get(opts, :raise_on_not_loaded?, true) | |
| Enum.reduce(data, %{}, fn | |
| {k, %Ecto.Association.NotLoaded{}}, acc -> | |
| if k in allow_not_loaded or not raise_on_not_loaded? do | |
| acc | |
| else | |
| raise Plausible.Audit.EncoderError, | |
| message: | |
| "#{k} association not loaded. Either preload, exclude or mark it as :allow_not_loaded in #{__MODULE__} options" | |
| end | |
| {k, v}, acc -> | |
| Map.put(acc, k, Plausible.Audit.Encoder.encode(v, opts)) | |
| end) | |
| end | |
| end | |
| defimpl Plausible.Audit.Encoder, for: [Integer, BitString, Float] do | |
| def encode(x, _opts \\ []), do: x | |
| end | |
| defimpl Plausible.Audit.Encoder, for: [DateTime, Date, NaiveDateTime, Time] do | |
| def encode(x, _opts \\ []), do: to_string(x) | |
| end | |
| defimpl Plausible.Audit.Encoder, for: Atom do | |
| def encode(x, opts \\ []) | |
| def encode(nil, _opts), do: nil | |
| def encode(true, _opts), do: true | |
| def encode(false, _opts), do: false | |
| def encode(x, _opts), do: Atom.to_string(x) | |
| end | |
| defimpl Plausible.Audit.Encoder, for: List do | |
| def encode(x, opts \\ []) do | |
| Enum.map(x, &Plausible.Audit.Encoder.encode(&1, opts)) | |
| end | |
| end | |
| defimpl Plausible.Audit.Encoder, for: Any do | |
| defmacro __deriving__(module, struct, options) do | |
| deriving(module, struct, options) | |
| end | |
| def deriving(module, _struct, options) do | |
| only = options[:only] | |
| except = options[:except] | |
| allow_not_loaded = options[:allow_not_loaded] || [] | |
| extractor = | |
| cond do | |
| only -> | |
| quote( | |
| do: | |
| struct | |
| |> Map.take(unquote(only)) | |
| |> Map.put(:__allow_not_loaded__, unquote(allow_not_loaded)) | |
| ) | |
| except -> | |
| except = [:__struct__ | except] | |
| quote( | |
| do: | |
| struct | |
| |> Map.drop( | |
| unquote(except) | |
| |> Map.put(:__allow_not_loaded__, unquote(allow_not_loaded)) | |
| ) | |
| ) | |
| true -> | |
| quote( | |
| do: | |
| struct | |
| |> Map.delete(:__struct__) | |
| |> Map.put(:__allow_not_loaded__, unquote(allow_not_loaded)) | |
| ) | |
| end | |
| quote do | |
| defimpl Plausible.Audit.Encoder, for: unquote(module) do | |
| def encode(struct, opts \\ []) do | |
| Plausible.Audit.Encoder.encode(unquote(extractor), opts) | |
| end | |
| end | |
| end | |
| end | |
| def encode(_), do: raise("Implement me") | |
| def encode(_, _), do: raise("Implement me") | |
| end | |