osmo_util: Introduce a tuple tree walker (osmo_util:tuple_walk())
diff --git a/src/osmo_util.erl b/src/osmo_util.erl
index bc6a885..60a9714 100644
--- a/src/osmo_util.erl
+++ b/src/osmo_util.erl
@@ -22,6 +22,7 @@
-export([digit_list2int/1, int2digit_list/1]).
-export([reload_config/0]).
+-export([tuple_walk/2, tuple_walk_print_cb/2]).
% Convert a list of digits to an integer value
digit_list2int(Int, []) ->
@@ -73,3 +74,35 @@
{error, _Reason} ->
lists:keyreplace(env, 1, AppList, {env, []})
end.
+
+
+% Walk a named tuple and (recursively) all its fields, call user-supplied
+% callback for each of them
+tuple_walk(Tpl, TupleCb) when is_tuple(Tpl), is_function(TupleCb) ->
+ tuple_walk([], Tpl, TupleCb).
+
+tuple_walk(Path, Tpl, TupleCb) when is_list(Path), is_tuple(Tpl) ->
+ % call Callback
+ NewTpl = TupleCb(Path, Tpl),
+ [TplName|TplList] = tuple_to_list(NewTpl),
+ NewTplList = tuple_fieldlist_walk(Path, TplName, TplList, TupleCb),
+ list_to_tuple([TplName|NewTplList]).
+
+tuple_fieldlist_walk(Path, TplName, FieldList, TupleCb) ->
+ tuple_fieldlist_walk(Path, TplName, FieldList, TupleCb, []).
+
+tuple_fieldlist_walk(_Path, _TplName, [], _TplCb, OutList) ->
+ OutList;
+tuple_fieldlist_walk(Path, TplName, [Head|List], TupleCb, OutList) ->
+ if
+ is_tuple(Head) ->
+ NewHead = tuple_walk(Path++[TplName], Head, TupleCb);
+ true ->
+ NewHead = Head
+ end,
+ tuple_fieldlist_walk(Path, TplName, List, TupleCb, OutList++[NewHead]).
+
+
+tuple_walk_print_cb(Path, Tpl) when is_list(Path), is_tuple(Tpl) ->
+ io:format("~p:~p~n", [Path, Tpl]),
+ Tpl.