Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions src/khepri_path.erl
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@

-export([compile/1,
from_string/1,
from_binary/1,
maybe_from_string/1,
to_string/1,
to_binary/1,
combine_with_conditions/2,
targets_specific_node/1,
component_targets_specific_node/1,
Expand Down Expand Up @@ -107,17 +109,38 @@
compile(PathPattern) ->
lists:map(fun khepri_condition:compile/1, PathPattern).

-spec from_string(MaybeString) -> PathPattern when
MaybeString :: string() | pattern(),
-spec from_string(String) -> PathPattern when
String :: string() | binary() | pattern(),
PathPattern :: pattern().
%% @doc Converts a Unix-like path to a native path.
%%
%% The Unix-like string can be either an Erlang string or an Erlang binary.
%%
%% For convenience, a native path is also accepted and returned as-is.

from_string("/" ++ MaybeString) ->
from_string(MaybeString, [?ROOT_NODE]);
from_string(MaybeString) when is_list(MaybeString) ->
from_string(MaybeString, []);
from_string(Binary) when is_binary(Binary) ->
String = erlang:binary_to_list(Binary),
from_string(String);
from_string(NotPath) ->
throw({invalid_path, #{path => NotPath}}).

-spec from_binary(String) -> PathPattern when
String :: string() | binary() | pattern(),
PathPattern :: pattern().
%% @doc Converts a Unix-like path to a native path.
%%
%% This is the same as calling `from_string(String)'. Therefore, it accepts
%% Erlang strings or binaries and native paths.
%%
%% @see from_string/1.

from_binary(MaybeString) ->
from_string(MaybeString).

from_string([Component | _] = Rest, ReversedPath)
when ?IS_NODE_ID(Component) orelse
?IS_CONDITION(Component) ->
Expand Down Expand Up @@ -253,6 +276,7 @@ maybe_from_string([Char1, Char2 | _] = Path)
end.

-spec to_string(path()) -> string().
%% @doc Converts a native path to a string.

to_string([?ROOT_NODE | Path]) ->
"/" ++
Expand All @@ -275,7 +299,15 @@ to_string(Path) ->
lists:map(fun component_to_string/1, Path),
"/").

-spec to_binary(path()) -> binary().
%% @doc Converts a native path to a binary.

to_binary(Path) ->
String = to_string(Path),
erlang:list_to_binary(String).

-spec component_to_string(component()) -> string().
%% @private

component_to_string(?ROOT_NODE) ->
"/";
Expand Down
38 changes: 38 additions & 0 deletions test/path_operations.erl
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,33 @@ glob_pattern_from_string_test() ->
[#if_name_matches{regex = "^.*foo.*bar.*$"}],
khepri_path:from_string("/*foo*bar*")).

from_binary_test() ->
?assertEqual(
[],
khepri_path:from_string(<<>>)),
?assertEqual(
['foo', <<"bar">>],
khepri_path:from_string(<<"/:foo/bar">>)),
?assertEqual(
[?THIS_NODE, <<"foo">>, ?PARENT_NODE],
khepri_path:from_string(<<"./foo/..">>)),
?assertEqual(
[#if_name_matches{regex = "^.*foo.*bar.*$"}],
khepri_path:from_string(<<"/*foo*bar*">>)),

?assertEqual(
[],
khepri_path:from_binary(<<>>)),
?assertEqual(
['foo', <<"bar">>],
khepri_path:from_binary(<<"/:foo/bar">>)),
?assertEqual(
[?THIS_NODE, <<"foo">>, ?PARENT_NODE],
khepri_path:from_binary(<<"./foo/..">>)),
?assertEqual(
[#if_name_matches{regex = "^.*foo.*bar.*$"}],
khepri_path:from_binary(<<"/*foo*bar*">>)).

%% -------------------------------------------------------------------
%% Path component serializing.
%% -------------------------------------------------------------------
Expand Down Expand Up @@ -213,6 +240,17 @@ path_with_binary_to_string_test() ->
"/bin%2Fary/:atom",
khepri_path:to_string([<<"bin/ary">>, atom])).

path_to_binary_test() ->
?assertEqual(
<<"/">>,
khepri_path:to_binary([])),
?assertEqual(
<<"/:foo/bar">>,
khepri_path:to_binary(['foo', <<"bar">>])),
?assertEqual(
<<"foo/..">>,
khepri_path:to_binary([?THIS_NODE, <<"foo">>, ?PARENT_NODE])).

%% -------------------------------------------------------------------
%% Combine path with conditions.
%% -------------------------------------------------------------------
Expand Down