THRIFT-5635 Update erlang client for Erlang 23-25
Client: erl
Patch: Sergey Yelin

This closes #2677

Summary of changes:
 - Add useful compiler options
 - Format sources using erlfmt
 - Switch to modern callbacks in thrift_* modules
 - Add static analysis (dialyzer), disabled by default
 - Add/fix types for API calls

NOTE: Enabling static analysis requires additional tweaks in multiplexer module.
diff --git a/lib/erl/src/thrift_client_util.erl b/lib/erl/src/thrift_client_util.erl
index 1dbe51e..7c5f094 100644
--- a/lib/erl/src/thrift_client_util.erl
+++ b/lib/erl/src/thrift_client_util.erl
@@ -22,9 +22,11 @@
 -export([new/4]).
 -export([new_multiplexed/3, new_multiplexed/4]).
 
--type service_name()            :: nonempty_string().
--type service_module()          :: atom().
--type multiplexed_service_map() :: [{ServiceName::service_name(), ServiceModule::service_module()}].
+-type service_name() :: nonempty_string().
+-type service_module() :: atom().
+-type multiplexed_service_map() :: [
+    {ServiceName :: service_name(), ServiceModule :: service_module()}
+].
 
 %%
 %% Splits client options into client, protocol, and transport options
@@ -36,44 +38,47 @@
 
 split_options([], ProtoIn, TransIn) ->
     {ProtoIn, TransIn};
-
-split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn)
-  when OptKey =:= strict_read;
-       OptKey =:= strict_write;
-       OptKey =:= protocol ->
+split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn) when
+    OptKey =:= strict_read;
+    OptKey =:= strict_write;
+    OptKey =:= protocol
+->
     split_options(Rest, [Opt | ProtoIn], TransIn);
-
-split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn)
-  when OptKey =:= framed;
-       OptKey =:= connect_timeout;
-       OptKey =:= recv_timeout;
-       OptKey =:= sockopts;
-       OptKey =:= ssltransport;
-       OptKey =:= ssloptions->
+split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn) when
+    OptKey =:= framed;
+    OptKey =:= connect_timeout;
+    OptKey =:= recv_timeout;
+    OptKey =:= sockopts;
+    OptKey =:= ssltransport;
+    OptKey =:= ssloptions
+->
     split_options(Rest, ProtoIn, [Opt | TransIn]).
 
-
 %% Client constructor for the common-case of socket transports
-new(Host, Port, Service, Options)
-  when is_integer(Port), is_atom(Service), is_list(Options) ->
+new(Host, Port, Service, Options) when
+    is_integer(Port), is_atom(Service), is_list(Options)
+->
     {ProtoOpts, TransOpts0} = split_options(Options),
 
-    {TransportModule, TransOpts2} = case lists:keytake(ssltransport, 1, TransOpts0) of
-                                        {value, {_, true}, TransOpts1} -> {thrift_sslsocket_transport, TransOpts1};
-                                        false -> {thrift_socket_transport, TransOpts0}
-                                    end,
+    {TransportModule, TransOpts2} =
+        case lists:keytake(ssltransport, 1, TransOpts0) of
+            {value, {_, true}, TransOpts1} -> {thrift_sslsocket_transport, TransOpts1};
+            false -> {thrift_socket_transport, TransOpts0}
+        end,
 
-    {ProtocolModule, ProtoOpts1} = case lists:keytake(protocol, 1, ProtoOpts) of
-                                     {value, {_, compact}, Opts} -> {thrift_compact_protocol, Opts};
-                                     {value, {_, json}, Opts} -> {thrift_json_protocol, Opts};
-                                     {value, {_, binary}, Opts} -> {thrift_binary_protocol, Opts};
-                                     false -> {thrift_binary_protocol, ProtoOpts}
-                                   end,
+    {ProtocolModule, ProtoOpts1} =
+        case lists:keytake(protocol, 1, ProtoOpts) of
+            {value, {_, compact}, Opts} -> {thrift_compact_protocol, Opts};
+            {value, {_, json}, Opts} -> {thrift_json_protocol, Opts};
+            {value, {_, binary}, Opts} -> {thrift_binary_protocol, Opts};
+            false -> {thrift_binary_protocol, ProtoOpts}
+        end,
     {ok, TransportFactory} =
         TransportModule:new_transport_factory(Host, Port, TransOpts2),
 
     {ok, ProtocolFactory} = ProtocolModule:new_protocol_factory(
-                              TransportFactory, ProtoOpts1),
+        TransportFactory, ProtoOpts1
+    ),
 
     case ProtocolFactory() of
         {ok, Protocol} ->
@@ -83,30 +88,49 @@
     end.
 
 -spec new_multiplexed(Host, Port, Services, Options) -> {ok, ServiceThriftClientList} when
-    Host        :: nonempty_string(),
-    Port        :: non_neg_integer(),
-    Services    :: multiplexed_service_map(),
-    Options     :: list(),
-    ServiceThriftClientList :: [{ServiceName::list(), ThriftClient::term()}].
-new_multiplexed(Host, Port, Services, Options) when is_integer(Port),
-                                                    is_list(Services),
-                                                    is_list(Options) ->
-    new_multiplexed(thrift_socket_transport:new_transport_factory(Host, Port, Options), Services, Options).
+    Host :: nonempty_string(),
+    Port :: non_neg_integer(),
+    Services :: multiplexed_service_map(),
+    Options :: list(),
+    ServiceThriftClientList :: [{ServiceName :: list(), ThriftClient :: term()}].
+new_multiplexed(Host, Port, Services, Options) when
+    is_integer(Port),
+    is_list(Services),
+    is_list(Options)
+->
+    new_multiplexed(
+        thrift_socket_transport:new_transport_factory(Host, Port, Options), Services, Options
+    ).
 
--spec new_multiplexed(TransportFactoryTuple, Services, Options) -> {ok, ServiceThriftClientList} when
-    TransportFactoryTuple   :: {ok, TransportFactory::term()},
-    Services                :: multiplexed_service_map(),
-    Options                 :: list(),
-    ServiceThriftClientList :: [{ServiceName::service_name(), ThriftClient::term()}].
-new_multiplexed(TransportFactoryTuple, Services, Options) when is_list(Services),
-                                                               is_list(Options),
-                                                               is_tuple(TransportFactoryTuple) ->
+-spec new_multiplexed(TransportFactoryTuple, Services, Options) ->
+    {ok, ServiceThriftClientList}
+when
+    TransportFactoryTuple :: {ok, TransportFactory :: term()},
+    Services :: multiplexed_service_map(),
+    Options :: list(),
+    ServiceThriftClientList :: [{ServiceName :: service_name(), ThriftClient :: term()}].
+new_multiplexed(TransportFactoryTuple, Services, Options) when
+    is_list(Services),
+    is_list(Options),
+    is_tuple(TransportFactoryTuple)
+->
     {ProtoOpts, _} = split_options(Options),
 
     {ok, TransportFactory} = TransportFactoryTuple,
 
-    {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(TransportFactory, ProtoOpts),
+    {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(
+        TransportFactory, ProtoOpts
+    ),
 
     {ok, Protocol} = ProtocolFactory(),
 
-    {ok, [{ServiceName, element(2, thrift_client:new(element(2, thrift_multiplexed_protocol:new(Protocol, ServiceName)), Service))} || {ServiceName, Service} <- Services]}.
+    {ok, [
+        {ServiceName,
+            element(
+                2,
+                thrift_client:new(
+                    element(2, thrift_multiplexed_protocol:new(Protocol, ServiceName)), Service
+                )
+            )}
+     || {ServiceName, Service} <- Services
+    ]}.