| defmodule Plausible.Stats.JSONSchema.Utils do |
| @moduledoc """ |
| Module for traversing and modifying JSON schemas. |
| """ |
|
|
| @type json :: map() | list() | String.t() | number() | boolean() | nil |
| @type transform_fun :: (json() -> json() | :remove) |
|
|
| @spec traverse(map(), transform_fun()) :: map() | :remove |
| def traverse(json, fun) when is_map(json) do |
| result = |
| Enum.reduce(json, %{}, fn {k, v}, acc -> |
| case traverse(v, fun) do |
| :remove -> acc |
| transformed_v -> Map.put(acc, k, transformed_v) |
| end |
| end) |
|
|
| case result do |
| map when map_size(map) == 0 -> fun.(%{}) |
| map -> fun.(map) |
| end |
| end |
|
|
| @spec traverse(list(), transform_fun()) :: list() | :remove |
| def traverse(json, fun) when is_list(json) do |
| result = |
| Enum.reduce(json, [], fn v, acc -> |
| case traverse(v, fun) do |
| :remove -> acc |
| transformed_v -> [transformed_v | acc] |
| end |
| end) |
| |> Enum.reverse() |
|
|
| case result do |
| [] -> fun.([]) |
| list -> fun.(list) |
| end |
| end |
|
|
| @spec traverse(String.t() | number() | boolean() | nil, transform_fun()) :: json() | :remove |
| def traverse(value, fun), do: fun.(value) |
| end |
|
|