Current section
Files
Jump to
Current section
Files
src/gleam_community@path.erl
-module(gleam_community@path).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-export([from_string/1, and_then/2, and_then_string/2, append/2, append_string/2, absolute/1, relative/1, absolute_or_resolve_from/2, to_string/1, equals/3]).
-export_type([path/0, path_kind/0]).
-opaque path() :: {path, list(binary()), path_kind()}.
-type path_kind() :: absolute | relative.
-spec normalize_segments_for(path_kind()) -> fun((list(binary()), binary()) -> list(binary())).
normalize_segments_for(Kind) ->
fun(Segments, Segment) -> case Segment of
<<".."/utf8>> ->
Only_up_from_here = gleam@list:all(
Segments,
fun(Segment@1) -> Segment@1 =:= <<".."/utf8>> end
),
case {Kind, Only_up_from_here} of
{relative, true} ->
[Segment | Segments];
{_, _} ->
gleam@result:unwrap(gleam@list:rest(Segments), [])
end;
<<""/utf8>> ->
case {Kind, Segments} of
{relative, []} ->
[<<"."/utf8>>];
{_, _} ->
Segments
end;
<<"."/utf8>> ->
case {Kind, Segments} of
{relative, []} ->
[<<"."/utf8>>];
{_, _} ->
Segments
end;
_ ->
[Segment | Segments]
end end.
-spec from_string(binary()) -> path().
from_string(Path_string) ->
Kind = case gleam@string:starts_with(Path_string, <<"/"/utf8>>) of
true ->
absolute;
false ->
relative
end,
_pipe = Path_string,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = gleam@list:fold(_pipe@1, [], normalize_segments_for(Kind)),
{path, _pipe@2, Kind}.
-spec and_then(path(), path()) -> path().
and_then(Self, Piece) ->
case erlang:element(3, Piece) of
absolute ->
Piece;
relative ->
Segments = begin
_pipe = erlang:element(2, Piece),
_pipe@1 = gleam@list:reverse(_pipe),
gleam@list:fold(
_pipe@1,
erlang:element(2, Self),
normalize_segments_for(erlang:element(3, Self))
)
end,
erlang:setelement(2, Self, Segments)
end.
-spec and_then_string(path(), binary()) -> path().
and_then_string(Self, Piece) ->
Piece@1 = from_string(Piece),
and_then(Self, Piece@1).
-spec append(path(), path()) -> path().
append(Self, Piece) ->
Segments = begin
_pipe = erlang:element(2, Piece),
gleam@list:fold(
_pipe,
erlang:element(2, Self),
normalize_segments_for(erlang:element(3, Self))
)
end,
erlang:setelement(2, Self, Segments).
-spec append_string(path(), binary()) -> path().
append_string(Self, Piece) ->
Segments = begin
_pipe = Piece,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
gleam@list:fold(
_pipe@1,
erlang:element(2, Self),
normalize_segments_for(erlang:element(3, Self))
)
end,
erlang:setelement(2, Self, Segments).
-spec absolute(path()) -> path().
absolute(Self) ->
erlang:setelement(3, Self, absolute).
-spec relative(path()) -> path().
relative(Self) ->
erlang:setelement(3, Self, relative).
-spec absolute_or_resolve_from(path(), binary()) -> path().
absolute_or_resolve_from(Self, Root) ->
case erlang:element(3, Self) of
absolute ->
Self;
relative ->
_pipe = from_string(Root),
append(_pipe, Self)
end.
-spec to_string(path()) -> binary().
to_string(Self) ->
Joined_segments = begin
_pipe = erlang:element(2, Self),
_pipe@1 = gleam@list:reverse(_pipe),
gleam@string:join(_pipe@1, <<"/"/utf8>>)
end,
case erlang:element(3, Self) of
absolute ->
<<"/"/utf8, Joined_segments/binary>>;
relative ->
Joined_segments
end.
-spec equals(path(), list(binary()), path_kind()) -> boolean().
equals(Self, Segments, Kind) ->
(gleam@list:reverse(erlang:element(2, Self)) =:= Segments) andalso (erlang:element(
3,
Self
)
=:= Kind).