I started using maybe
in my codebase.
I have this kind of code:
discover_iface_type(Ifname) ->
maybe
{ok, Device} ?= validate_input:device(Ifname),
{ok, DevInfo} ?= ip_addr_dev_info(Device),
case maps:get(ifi_type, DevInfo, undefined) of
undefined ->
{error, not_tunnel};
Type when is_atom(Type) ->
{ok, Type}
end
else
{error, _Reason} = E ->
E
end.
the problem with this is that I’d like to write:
discover_iface_type(Ifname) ->
maybe
{ok, Device} ?= validate_input:device(Ifname),
{ok, DevInfo} ?= ip_addr_dev_info(Device),
Type when is_atom(Type) ?= maps:get(ifi_type, DevInfo, undefined),
{ok, Type}
else
undefined -> {error, not_found};
{error, _Reason} = E ->
E
end.
One alternative is to write a more tedious code like:
discover_iface_type(Ifname) ->
Getter = fun
(undefined) -> {error, no_tunnel};
(V) -> {ok, V}
end,
maybe
{ok, Device} ?= validate_input:device(Ifname),
{ok, DevInfo} ?= ip_addr_dev_info(Device),
{ok, Type} ?= Getter(maps:get(ifi_type, DevInfo, undefined)
{ok, Type}
else
{error, _Reason} = E -> E
end.
But we can extends the maps
module to implement the fetch
function like the Elixir Map.fetch
discover_iface_type(Ifname) ->
maybe
{ok, Device} ?= validate_input:device(Ifname),
{ok, DevInfo} ?= ip_addr_dev_info(Device),
{ok, Type} ?= maps:fetch(ifi_type, DevInfo)
{ok, Type}
else
error -> {error, not_found};
{error, _Reason} = E -> E
end.
What do you think?