-module(dream_http_client@matching). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/dream_http_client/matching.gleam"). -export([match_url_only/0, build_signature/2, requests_match/3]). -export_type([matching_config/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Request matching logic\n" "\n" " Determines if a request matches a recorded request based on configurable\n" " matching criteria (method, URL, headers, body).\n" ). -type matching_config() :: {matching_config, boolean(), boolean(), boolean(), boolean()}. -file("src/dream_http_client/matching.gleam", 30). ?DOC( " Default matching configuration: match on method and URL only\n" "\n" " This ignores headers and body, which is practical for most use cases\n" " since headers often contain timestamps, auth tokens, etc., and bodies\n" " may contain dynamic IDs.\n" ). -spec match_url_only() -> matching_config(). match_url_only() -> {matching_config, true, true, false, false}. -file("src/dream_http_client/matching.gleam", 81). -spec method_to_string(gleam@http:method()) -> binary(). method_to_string(Method) -> case Method of get -> <<"GET"/utf8>>; post -> <<"POST"/utf8>>; put -> <<"PUT"/utf8>>; delete -> <<"DELETE"/utf8>>; patch -> <<"PATCH"/utf8>>; head -> <<"HEAD"/utf8>>; options -> <<"OPTIONS"/utf8>>; trace -> <<"TRACE"/utf8>>; connect -> <<"CONNECT"/utf8>>; {other, S} -> string:uppercase(S) end. -file("src/dream_http_client/matching.gleam", 113). -spec scheme_to_string(gleam@http:scheme()) -> binary(). scheme_to_string(Scheme) -> case Scheme of http -> <<"http"/utf8>>; https -> <<"https"/utf8>> end. -file("src/dream_http_client/matching.gleam", 96). -spec build_url(dream_http_client@recording:recorded_request()) -> binary(). build_url(Req) -> Port_string = case erlang:element(5, Req) of {some, P} -> <<":"/utf8, (erlang:integer_to_binary(P))/binary>>; none -> <<""/utf8>> end, Query_string = case erlang:element(7, Req) of {some, Q} -> <<"?"/utf8, Q/binary>>; none -> <<""/utf8>> end, <<<<<<<<<<(scheme_to_string(erlang:element(3, Req)))/binary, "://"/utf8>>/binary, (erlang:element(4, Req))/binary>>/binary, Port_string/binary>>/binary, (erlang:element(6, Req))/binary>>/binary, Query_string/binary>>. -file("src/dream_http_client/matching.gleam", 127). -spec compare_header_names({binary(), binary()}, {binary(), binary()}) -> gleam@order:order(). compare_header_names(Header1, Header2) -> gleam@string:compare(erlang:element(1, Header1), erlang:element(1, Header2)). -file("src/dream_http_client/matching.gleam", 134). -spec format_header_pair({binary(), binary()}) -> binary(). format_header_pair(Header) -> <<<<(erlang:element(1, Header))/binary, ":"/utf8>>/binary, (erlang:element(2, Header))/binary>>. -file("src/dream_http_client/matching.gleam", 120). -spec headers_to_string(list({binary(), binary()})) -> binary(). headers_to_string(Headers) -> Sorted = gleam@list:sort(Headers, fun compare_header_names/2), Header_strings = gleam@list:map(Sorted, fun format_header_pair/1), gleam@string:join(Header_strings, <<"|"/utf8>>). -file("src/dream_http_client/matching.gleam", 43). ?DOC( " Build a request signature for matching\n" "\n" " Creates a string signature from the request based on the matching\n" " configuration. This signature is used as a key to look up recordings.\n" ). -spec build_signature( dream_http_client@recording:recorded_request(), matching_config() ) -> binary(). build_signature(Request, Config) -> Method_str = case erlang:element(2, Config) of true -> method_to_string(erlang:element(2, Request)); false -> <<""/utf8>> end, Url_str = case erlang:element(3, Config) of true -> build_url(Request); false -> <<""/utf8>> end, Headers_str = case erlang:element(4, Config) of true -> headers_to_string(erlang:element(8, Request)); false -> <<""/utf8>> end, Body_str = case erlang:element(5, Config) of true -> erlang:element(9, Request); false -> <<""/utf8>> end, <<<<<>/binary, Headers_str/binary>>/binary, Body_str/binary>>. -file("src/dream_http_client/matching.gleam", 71). ?DOC(" Check if two requests match based on the configuration\n"). -spec requests_match( dream_http_client@recording:recorded_request(), dream_http_client@recording:recorded_request(), matching_config() ) -> boolean(). requests_match(Request1, Request2, Config) -> Sig1 = build_signature(Request1, Config), Sig2 = build_signature(Request2, Config), Sig1 =:= Sig2.