aboutsummaryrefslogtreecommitdiff
path: root/src/gleam_stdlib_decode_ffi.erl
blob: 35af05e74184c0e4371283159d5a74efa934200d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
-module(gleam_stdlib_decode_ffi).

-export([strict_index/2, list/5, dict/1]).

strict_index([X | _], 0) ->
    {ok, {some, X}};
strict_index([_, X | _], 1) ->
    {ok, {some, X}};
strict_index(Tuple, Index) when is_tuple(Tuple) andalso is_integer(Index) ->
    {ok, try
        {some, element(Index + 1, Tuple)}
    catch _:_ -> 
        none
    end};
strict_index(Map, Key) when is_map(Map) ->
    {ok, try
        {some, maps:get(Key, Map)}
    catch _:_ -> 
        none
    end};
strict_index(_, Index) when is_integer(Index) ->
    {error, <<"Indexable">>};
strict_index(_, _) ->
    {error, <<"Dict">>}.

list(T, A, B, C, D) when is_tuple(T) ->
    list(tuple_to_list(T), A, B, C, D);
list([], _, _, _, Acc) ->
    {lists:reverse(Acc), []};
list([X | Xs], Decode, PushPath, Index, Acc) ->
    {Out, Errors} = Decode(X),
    case Errors of
        [] -> list(Xs, Decode, PushPath, Index + 1, [Out | Acc]);
        _ -> PushPath({[], Errors}, integer_to_binary(Index))
    end;
list(Unexpected, _, _, _, []) ->
    Found = gleam@dynamic:classify(Unexpected),
    Error = {decode_error, <<"List"/utf8>>, Found, []},
    {[], [Error]};
list(_, _, _, _, Acc) ->
    {lists:reverse(Acc), []}.

dict(#{} = Data) -> {ok, Data};
dict(_) -> {error, nil}.