Skip to content

Instantly share code, notes, and snippets.

@soranoba
Last active September 18, 2019 17:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soranoba/2d0c53b3c293beb011f5a2fcbe961648 to your computer and use it in GitHub Desktop.
Save soranoba/2d0c53b3c293beb011f5a2fcbe961648 to your computer and use it in GitHub Desktop.
How to access array index with bbmustache (v1.8.0). There are no plans to support official this.

This patch is provided with the same license as bbmustache.
If you patch bbmustache, you don't need to worry about the license.

diff --git a/src/bbmustache.erl b/src/bbmustache.erl
index 0d43d74..965c8f7 100644
--- a/src/bbmustache.erl
+++ b/src/bbmustache.erl
@@ -628,13 +628,17 @@ get_data_recursive_impl([], Data, _) ->
get_data_recursive_impl([<<".">>], Data, _) ->
{ok, Data};
get_data_recursive_impl([Key | RestKey] = Keys, Data, #?MODULE{context_stack = Stack} = State) ->
- case is_recursive_data(Data) andalso find_data(convert_keytype(Key, State), Data) of
- {ok, ChildData} ->
- get_data_recursive_impl(RestKey, ChildData, State#?MODULE{context_stack = []});
- _ when Stack =:= [] ->
- error;
- _ ->
- get_data_recursive_impl(Keys, hd(Stack), State#?MODULE{context_stack = tl(Stack)})
+ case is_list(Data) andalso find_index_data_from_lists(Key, Data) of
+ {ok, ChildData} -> {ok, ChildData};
+ _ ->
+ case is_recursive_data(Data) andalso find_data(convert_keytype(Key, State), Data) of
+ {ok, ChildData} ->
+ get_data_recursive_impl(RestKey, ChildData, State#?MODULE{context_stack = []});
+ _ when Stack =:= [] ->
+ error;
+ _ ->
+ get_data_recursive_impl(Keys, hd(Stack), State#?MODULE{context_stack = tl(Stack)})
+ end
end.
%% @doc find the value of the specified key from {@link recursive_data/0}
@@ -669,3 +673,25 @@ is_recursive_data(_) -> false.
is_recursive_data([Tuple | _]) when is_tuple(Tuple) -> true;
is_recursive_data(_) -> false.
-endif.
+
+%% @doc When the value can convert integer, it returns the integer. Otherwise it returns error.
+-spec safe_binary_to_integer(binary()) -> integer() | error.
+safe_binary_to_integer(Bin) ->
+ try
+ binary_to_integer(Bin)
+ catch _:_ ->
+ error
+ end.
+
+-spec find_index_data_from_lists(binary(), list()) -> {ok, term()} | error.
+find_index_data_from_lists(IndexBin, List) ->
+ case safe_binary_to_integer(IndexBin) of
+ Index when is_integer(Index), Index >= 0 ->
+ try
+ {ok, lists:nth(Index + 1, List)}
+ catch _:_ ->
+ error
+ end;
+ _ ->
+ error
+ end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment