Packages

A gRPC client library for Erlang built on top of gun.

Current section

Files

Jump to
egrpc src egrpc_grpc.erl
Raw

src/egrpc_grpc.erl

-module(egrpc_grpc).
-export([encode/2, decode/3]).
-export_type([http_encoding/0]).
-type http_encoding() :: identity | gzip.
-spec encode(http_encoding(), binary()) -> binary().
encode(identity, Bin) ->
Length = byte_size(Bin),
<<0, Length:32, Bin/binary>>;
encode(gzip, Bin) ->
CompressedBin = zlib:gzip(Bin),
Length = byte_size(CompressedBin),
<<1, Length:32, CompressedBin/binary>>;
encode(Encoding, _) ->
throw({error, {unknown_encoding, Encoding}}).
-spec decode(http_encoding(), Decoder, binary()) -> Result when
Decoder :: egrpc_codec:decoder(),
Result :: {ok, Msg :: term(), Rest :: binary()}
| {error, egrpc:grpc_error() | any()}
| more.
decode(_Encoding, Decoder, <<0, Length:32, Bin:Length/binary, Rest/binary>>) ->
try
{ok, Decoder(Bin), Rest}
catch
_:Reason ->
{error, Reason}
end;
decode(_Encoding, _Decoder, <<0, _Length:32, _Binary/binary>>) -> more;
decode(gzip, Decoder, <<1, Length:32, Compressed:Length/binary, Rest/binary>>) ->
try
Bin = zlib:gunzip(Compressed),
{ok, Decoder(Bin), Rest}
catch
error:data_error ->
{error, {grpc_error, internal,
<<"Could not decompress but compression algorithm gzip is supported">>}};
_:_Reason ->
{error, {grpc_error, internal, <<"Error parsing response proto">>}}
end;
decode(Encoding, _Decoder, <<1, Length:32, _Compressed:Length/binary, _Rest/binary>>) ->
{error, {grpc_error, unimplemented,
<<"Compression mechanism ", (atom_to_binary(Encoding, utf8))/binary,
" used for received frame not supported">>
}};
decode(_Encoding, _Decoder, <<_/binary>>) ->
more.