Packages
surgex
4.7.0-git-5414
6.0.1
6.0.0
5.1.1
5.1.0
5.0.0
5.0.0-git-015aa39a
4.15.2
4.15.1
4.15.1-git-98b3
4.15.0
4.15.0-git-943e
4.15.0-git-5806
4.14.1
4.14.0
4.13.1
4.13.0
4.12.0
4.11.0
4.11.0-git-97d4
4.11.0-git-14c8
4.10.0
4.10.0-git-37f2
4.9.0
4.9.0-git-9d5f
4.8.1-git-80a7
4.8.0
4.8.0-git-fbda
4.8.0-git-e058
4.7.0
4.7.0-git-5414
4.6.1
4.6.0
4.5.0
4.4.0
4.3.0
4.2.1
4.2.0
4.1.1
4.1.1-git-9f6b
4.1.1-git-6f0cd
4.1.0
4.1.0-git-e934
4.1.0-git-8c28
4.1.0-git-56a9
4.1.0-git-55fd
4.0.0
3.2.8
3.2.7
3.2.6
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
retired
3.1.0
3.0.0
2.24.1
2.24.0
retired
2.23.0
2.22.0
2.21.0
2.20.1
2.20.0
2.19.0
2.18.1
2.18.0
2.17.0
2.16.0
2.15.0
2.14.0
2.13.0
2.12.1
2.12.0
2.11.0
2.10.0
2.9.0
2.8.0
2.7.0
2.6.0
2.5.1
2.5.0
2.4.0
retired
2.3.0
2.2.1
2.2.0
2.1.1
2.1.0
2.0.0
1.6.0
1.5.2
1.5.1
1.5.0
1.4.0
1.3.1
retired
1.3.0
retired
1.2.1
1.2.0
1.1.0
1.0.0
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
All Things Elixir @ Surge Ventures Inc, the creators of Fresha
Current section
Files
Jump to
Current section
Files
lib/surgex/parser/parsers/resource_array_parser.ex
defmodule Surgex.Parser.ResourceArrayParser do
@moduledoc false
@type errors :: :too_short | :too_long | :invalid_array
@type option :: {:min, integer()} | {:max, integer()}
@spec call(term(), (term() -> term()), [option()]) :: {:ok, list() | nil} | {:error, errors()}
def call(list, item_parser, opts \\ [])
def call(nil, _item_parser, _opts), do: {:ok, nil}
def call("", _item_parser, _opts), do: {:ok, nil}
def call(list, item_parser, opts) when is_list(list) do
min = Keyword.get(opts, :min)
max = Keyword.get(opts, :max)
case validate_length(list, min, max) do
{:ok, list} -> parse_array(list, item_parser)
{:error, :too_short} -> {:error, :too_short}
{:error, :too_long} -> {:error, :too_long}
end
end
def call(_input, _, _), do: {:error, :invalid_array}
defp validate_length(list, min, max) do
cond do
min && length(list) < min ->
{:error, :too_short}
max && length(list) > max ->
{:error, :too_long}
true ->
{:ok, list}
end
end
defp parse_array(list, item_parser) do
list
|> Enum.map(item_parser)
|> Stream.with_index()
|> Enum.reduce({[], []}, &reduce/2)
|> close
end
defp reduce({{:ok, result}, _index}, {output, errors}) do
{[result | output], errors}
end
defp reduce({{:error, error_type, pointers}, index}, {output, errors})
when error_type in [:invalid_parameters, :invalid_pointers] do
new_errors =
Enum.map(pointers, fn {reason, pointer} ->
{reason, "#{index}/#{pointer}"}
end)
{output, errors ++ new_errors}
end
defp close({output, []}), do: {:ok, Enum.reverse(output)}
defp close({_output, errors}), do: {:error, errors}
end