Packages

Neo4j driver for Elixir, using the fast Bolt protocol

Current section

Files

Jump to
boltx lib bolt_sips internals pack_stream encoder.ex
Raw

lib/bolt_sips/internals/pack_stream/encoder.ex

alias Bolt.Sips.Internals.PackStream
alias Bolt.Sips.Internals.PackStream.EncoderHelper
defprotocol Bolt.Sips.Internals.PackStream.Encoder do
@moduledoc false
# Encodes an item to its binary PackStream Representation
#
# Implementation exists for following types:
# - Integer
# - Float
# - List
# - Map
# - Struct (defined in the Bolt protocol)
@fallback_to_any true
@doc """
Encode entity into its Bolt binary represenation depending of the used bolt version
"""
@spec encode(any(), integer()) :: binary()
def encode(entity, bolt_version)
end
defimpl PackStream.Encoder, for: Atom do
def encode(data, bolt_version), do: EncoderHelper.call_encode(:atom, data, bolt_version)
end
defimpl PackStream.Encoder, for: BitString do
def encode(data, bolt_version), do: EncoderHelper.call_encode(:string, data, bolt_version)
end
defimpl PackStream.Encoder, for: Integer do
def encode(data, bolt_version), do: EncoderHelper.call_encode(:integer, data, bolt_version)
end
defimpl PackStream.Encoder, for: Float do
def encode(data, bolt_version), do: EncoderHelper.call_encode(:float, data, bolt_version)
end
defimpl PackStream.Encoder, for: List do
def encode(data, bolt_version), do: EncoderHelper.call_encode(:list, data, bolt_version)
end
defimpl PackStream.Encoder, for: Map do
def encode(data, bolt_version), do: EncoderHelper.call_encode(:map, data, bolt_version)
end
defimpl PackStream.Encoder, for: Time do
def encode(data, bolt_version), do: EncoderHelper.call_encode(:local_time, data, bolt_version)
end
defimpl PackStream.Encoder, for: Bolt.Sips.Types.TimeWithTZOffset do
def encode(data, bolt_version) do
EncoderHelper.call_encode(:time_with_tz, data, bolt_version)
end
end
defimpl PackStream.Encoder, for: Date do
def encode(data, bolt_version), do: EncoderHelper.call_encode(:date, data, bolt_version)
end
defimpl PackStream.Encoder, for: NaiveDateTime do
def encode(data, bolt_version) do
EncoderHelper.call_encode(:local_datetime, data, bolt_version)
end
end
defimpl PackStream.Encoder, for: DateTime do
def encode(data, version) do
EncoderHelper.call_encode(:datetime_with_tz_id, data, version)
end
end
defimpl PackStream.Encoder, for: Bolt.Sips.Types.DateTimeWithTZOffset do
def encode(data, version) do
EncoderHelper.call_encode(:datetime_with_tz_offset, data, version)
end
end
defimpl PackStream.Encoder, for: Bolt.Sips.Types.Duration do
def encode(data, version), do: EncoderHelper.call_encode(:duration, data, version)
end
defimpl PackStream.Encoder, for: Bolt.Sips.Types.Point do
def encode(data, version), do: EncoderHelper.call_encode(:point, data, version)
end
defimpl PackStream.Encoder, for: Any do
@spec encode({integer(), list()} | %{:__struct__ => String.t()}, integer()) ::
Bolt.Sips.Internals.PackStream.value() | <<_::16, _::_*8>>
def encode({signature, data}, bolt_version) when is_list(data) do
valid_signatures =
PackStream.Message.Encoder.valid_signatures(bolt_version) ++
Bolt.Sips.Internals.PackStream.MarkersHelper.valid_signatures()
if signature in valid_signatures do
EncoderHelper.call_encode(:struct, {signature, data}, bolt_version)
else
raise Bolt.Sips.Internals.PackStreamError,
message: "Unable to encode",
data: data,
bolt_version: bolt_version
end
end
# Elixir structs just need to be convertedd to map befoare being encoded
def encode(%{__struct__: _} = data, bolt_version) do
map = Map.from_struct(data)
PackStream.Encoder.encode(map, bolt_version)
end
def encode(data, bolt_version) do
raise Bolt.Sips.Internals.PackStreamError,
message: "Unable to encode",
data: data,
bolt_version: bolt_version
end
end