-module(stratus@internal@socket). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([convert_options/1, selector/0, get_certs/0, get_custom_matcher/0]). -export_type([socket/0, socket_reason/0, receive_mode/0, packet_type/0, options/0, shutdown/0, socket_message/0, erlang_socket_message/0]). -type socket() :: any(). -type socket_reason() :: closed | not_owner | badarg | {posix, binary()}. -type receive_mode() :: {count, integer()} | once | pull | all. -type packet_type() :: binary | list. -type options() :: {'receive', receive_mode()} | {packets_of, packet_type()} | {send_timeout, integer()} | {send_timeout_close, boolean()} | {reuseaddr, boolean()} | {nodelay, boolean()} | {cacerts, gleam@dynamic:dynamic_()} | {customize_hostname_check, gleam@dynamic:dynamic_()}. -type shutdown() :: read | write | read_write. -type socket_message() :: {data, bitstring()} | {err, socket_reason()}. -type erlang_socket_message() :: ssl | ssl_closed | ssl_error | tcp | tcp_closed | tcp_error. -spec convert_options(list(options())) -> list({gleam@erlang@atom:atom_(), gleam@dynamic:dynamic_()}). convert_options(Options) -> Active = erlang:binary_to_atom(<<"active"/utf8>>), gleam@list:map(Options, fun(Opt) -> case Opt of {'receive', {count, Count}} -> {Active, gleam@dynamic:from(Count)}; {'receive', once} -> {Active, gleam@dynamic:from( erlang:binary_to_atom(<<"once"/utf8>>) )}; {'receive', pull} -> {Active, gleam@dynamic:from(false)}; {'receive', all} -> {Active, gleam@dynamic:from(true)}; {packets_of, binary} -> {erlang:binary_to_atom(<<"mode"/utf8>>), gleam@dynamic:from(binary)}; {packets_of, list} -> {erlang:binary_to_atom(<<"mode"/utf8>>), gleam@dynamic:from(list)}; {cacerts, Data} -> {erlang:binary_to_atom(<<"cacerts"/utf8>>), Data}; {nodelay, Bool} -> {erlang:binary_to_atom(<<"nodelay"/utf8>>), gleam@dynamic:from(Bool)}; {reuseaddr, Bool@1} -> {erlang:binary_to_atom(<<"reuseaddr"/utf8>>), gleam@dynamic:from(Bool@1)}; {send_timeout, Int} -> {erlang:binary_to_atom(<<"send_timeout"/utf8>>), gleam@dynamic:from(Int)}; {send_timeout_close, Bool@2} -> {erlang:binary_to_atom(<<"send_timeout_close"/utf8>>), gleam@dynamic:from(Bool@2)}; {customize_hostname_check, Funcs} -> {erlang:binary_to_atom(<<"customize_hostname_check"/utf8>>), Funcs} end end). -spec decode_socket_error(gleam@dynamic:dynamic_()) -> {ok, socket_reason()} | {error, list(gleam@dynamic:decode_error())}. decode_socket_error(Dyn) -> _pipe = Dyn, _pipe@1 = gleam_erlang_ffi:atom_from_dynamic(_pipe), _pipe@2 = gleam@result:map(_pipe@1, fun erlang:atom_to_binary/1), gleam@result:map(_pipe@2, fun(Atom) -> case Atom of <<"closed"/utf8>> -> closed; <<"not_owner"/utf8>> -> not_owner; <<"badarg"/utf8>> -> badarg; Posix -> {posix, Posix} end end). -spec selector() -> gleam@erlang@process:selector(socket_message()). selector() -> _pipe = gleam_erlang_ffi:new_selector(), _pipe@2 = gleam@erlang@process:selecting_record3( _pipe, tcp, fun(_, Msg) -> _assert_subject = begin _pipe@1 = gleam@dynamic:bit_array(Msg), gleam@result:map(_pipe@1, fun(Field@0) -> {data, Field@0} end) end, {ok, Msg@1} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"stratus/internal/socket"/utf8>>, function => <<"selector"/utf8>>, line => 121}) end, Msg@1 end ), _pipe@4 = gleam@erlang@process:selecting_record3( _pipe@2, ssl, fun(_, Msg@2) -> _assert_subject@1 = begin _pipe@3 = gleam@dynamic:bit_array(Msg@2), gleam@result:map(_pipe@3, fun(Field@0) -> {data, Field@0} end) end, {ok, Msg@3} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"stratus/internal/socket"/utf8>>, function => <<"selector"/utf8>>, line => 127}) end, Msg@3 end ), _pipe@5 = gleam@erlang@process:selecting_record2( _pipe@4, ssl_closed, fun(_) -> {err, closed} end ), _pipe@6 = gleam@erlang@process:selecting_record2( _pipe@5, tcp_closed, fun(_) -> {err, closed} end ), _pipe@7 = gleam@erlang@process:selecting_record3( _pipe@6, tcp_error, fun(_, Reason) -> _assert_subject@2 = decode_socket_error(Reason), {ok, Err} = case _assert_subject@2 of {ok, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"stratus/internal/socket"/utf8>>, function => <<"selector"/utf8>>, line => 135}) end, {err, Err} end ), gleam@erlang@process:selecting_record3( _pipe@7, ssl_error, fun(_, Reason@1) -> _assert_subject@3 = decode_socket_error(Reason@1), {ok, Err@1} = case _assert_subject@3 of {ok, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"stratus/internal/socket"/utf8>>, function => <<"selector"/utf8>>, line => 139}) end, {err, Err@1} end ). -spec get_certs() -> gleam@dynamic:dynamic_(). get_certs() -> public_key:cacerts_get(). -spec get_custom_matcher() -> options(). get_custom_matcher() -> stratus_ffi:custom_sni_matcher().