-module(gleam@uri). -compile(no_auto_import). -export([erl_parse/1, parse/1, parse_query/1, query_to_string/1, path_segments/1, to_string/1, origin/1, merge/2]). erl_parse(A) -> uri_string:parse(A). parse(String) -> case gleam@result:nil_error(gleam@dynamic:map(uri_string:parse(String))) of {error, GleamTryError} -> {error, GleamTryError}; {ok, UriMap} -> Get = fun(K, DecodeType) -> gleam@option:from_result( gleam@result:then( gleam@map:get(UriMap, gleam@dynamic:from(K)), gleam@function:compose( DecodeType, fun gleam@result:nil_error/1 ) ) ) end, Uri = {uri, Get(scheme, fun gleam@dynamic:string/1), Get(userinfo, fun gleam@dynamic:string/1), Get(host, fun gleam@dynamic:string/1), Get(port, fun gleam@dynamic:int/1), gleam@option:unwrap( Get(path, fun gleam@dynamic:string/1), <<""/utf8>> ), Get(query, fun gleam@dynamic:string/1), Get(fragment, fun gleam@dynamic:string/1)}, {ok, Uri} end. parse_query(Query) -> gleam@result:nil_error( gleam@dynamic:typed_list( uri_string:dissect_query(Query), fun(GleamCaptureVariable) -> gleam@dynamic:typed_tuple2( GleamCaptureVariable, fun gleam@dynamic:string/1, fun gleam@dynamic:string/1 ) end ) ). query_to_string(Query) -> gleam@result:unwrap( gleam@dynamic:string( uri_string:compose_query(Query, [{encoding, utf8}]) ), <<""/utf8>> ). do_remove_dot_segments(Input, Accumulator) -> case Input of [] -> gleam@list:reverse(Accumulator); [Segment | Rest] -> Accumulator5 = case {Segment, Accumulator} of {<<""/utf8>>, Accumulator1} -> Accumulator1; {<<"."/utf8>>, Accumulator2} -> Accumulator2; {<<".."/utf8>>, []} -> []; {<<".."/utf8>>, [_ | Accumulator3]} -> Accumulator3; {Segment1, Accumulator4} -> [Segment1 | Accumulator4] end, do_remove_dot_segments(Rest, Accumulator5) end. remove_dot_segments(Input) -> do_remove_dot_segments(Input, []). path_segments(Path) -> remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). to_string(Uri) -> Field = fun(Key, Value) -> gleam@result:map( gleam@option:to_result(Value, nil), fun(Value1) -> {Key, gleam@dynamic:from(Value1)} end ) end, gleam@result:unwrap( gleam@dynamic:string( uri_string:recompose( gleam@map:from_list( gleam@list:filter_map( [Field(scheme, erlang:element(2, Uri)), Field(userinfo, erlang:element(3, Uri)), Field(host, erlang:element(4, Uri)), Field(port, erlang:element(5, Uri)), Field(path, {some, erlang:element(6, Uri)}), Field(query, erlang:element(7, Uri)), Field(fragment, erlang:element(8, Uri))], fun(X) -> X end ) ) ) ), <<""/utf8>> ). origin(Uri) -> {uri, Scheme, _, Host, Port, _, _, _} = Uri, case Scheme of {some, <<"https"/utf8>>} -> Origin = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, {ok, to_string(Origin)}; {some, <<"http"/utf8>>} -> Origin = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, {ok, to_string(Origin)}; _ -> {error, nil} end. drop_last(Elements) -> {Keep, _} = gleam@list:split(Elements, gleam@list:length(Elements) - 1), Keep. join_segments(Segments) -> case Segments of [] -> <<""/utf8>>; _ -> gleam@string:append( <<"/"/utf8>>, gleam@string:join(Segments, <<"/"/utf8>>) ) end. merge(Base, Relative) -> case Base of {uri, {some, _}, _, {some, _}, _, _, _, _} -> case Relative of {uri, {some, _}, _, _, _, _, _, _} -> Path = join_segments( remove_dot_segments( gleam@string:split( erlang:element(6, Relative), <<"/"/utf8>> ) ) ), Resolved = {uri, erlang:element(2, Relative), none, erlang:element(4, Relative), erlang:element(5, Relative), Path, erlang:element(7, Relative), erlang:element(8, Relative)}, {ok, Resolved}; {uri, none, _, {some, _}, _, _, _, _} -> Path1 = join_segments( remove_dot_segments( gleam@string:split( erlang:element(6, Relative), <<"/"/utf8>> ) ) ), Resolved1 = {uri, erlang:element(2, Base), none, erlang:element(4, Relative), erlang:element(5, Relative), Path1, erlang:element(7, Relative), erlang:element(8, Relative)}, {ok, Resolved1}; {uri, none, _, none, _, <<""/utf8>>, _, _} -> Resolved2 = {uri, erlang:element(2, Base), none, erlang:element(4, Base), erlang:element(5, Base), erlang:element(6, Base), gleam@option:'or'( erlang:element(7, Relative), erlang:element(7, Base) ), erlang:element(8, Relative)}, {ok, Resolved2}; {uri, none, _, none, _, Path2, _, _} -> case gleam@string:starts_with(Path2, <<"/"/utf8>>) of true -> Path3 = join_segments( remove_dot_segments( gleam@string:split( erlang:element(6, Relative), <<"/"/utf8>> ) ) ), Resolved3 = {uri, erlang:element(2, Base), none, erlang:element(4, Base), erlang:element(5, Base), Path3, erlang:element(7, Relative), erlang:element(8, Relative)}, {ok, Resolved3}; false -> Path4 = join_segments( remove_dot_segments( gleam@list:append( drop_last( gleam@string:split( erlang:element(6, Base), <<"/"/utf8>> ) ), gleam@string:split( erlang:element(6, Relative), <<"/"/utf8>> ) ) ) ), Resolved4 = {uri, erlang:element(2, Base), none, erlang:element(4, Base), erlang:element(5, Base), Path4, erlang:element(7, Relative), erlang:element(8, Relative)}, {ok, Resolved4} end end; _ -> {error, nil} end.