defmodule Bolt.Sips.Internals.PackStream.V2 do alias Bolt.Sips.Types.{TimeWithTZOffset, DateTimeWithTZOffset, Duration, Point} alias Bolt.Sips.Internals.PackStream.Encoder defmacro __using__(_options) do quote do import unquote(__MODULE__) @last_version Bolt.Sips.Internals.BoltVersionHelper.last() # Local Time @local_time_signature 0x74 # Time With TZ Offset @time_with_tz_signature 0x54 # Date @date_signature 0x44 # Local DateTime @local_datetime_signature 0x64 # Datetime with TZ offset @datetime_with_zone_offset_signature 0x46 # Datetime with TZ id @datetime_with_zone_id_signature 0x66 # Duration @duration_signature 0x45 # Point 2D @point2d_signature 0x58 # Point 3D @point3d_signature 0x59 defp do_call_encode(:local_time, local_time, bolt_version) when bolt_version >= 2 and bolt_version <= @last_version do Encoder.encode({@local_time_signature, [day_time(local_time)]}, bolt_version) end defp do_call_encode( :time_with_tz, %TimeWithTZOffset{time: time, timezone_offset: offset}, bolt_version ) when bolt_version >= 2 and bolt_version <= @last_version do Encoder.encode({@time_with_tz_signature, [day_time(time), offset]}, bolt_version) end defp do_call_encode(:date, date, bolt_version) when bolt_version >= 2 and bolt_version <= @last_version do epoch = Date.diff(date, ~D[1970-01-01]) Encoder.encode({@date_signature, [epoch]}, bolt_version) end defp do_call_encode(:local_datetime, local_datetime, bolt_version) when bolt_version >= 2 and bolt_version <= @last_version do Encoder.encode( {@local_datetime_signature, decompose_datetime(local_datetime)}, bolt_version ) end defp do_call_encode(:datetime_with_tz_id, datetime, bolt_version) when bolt_version >= 2 and bolt_version <= @last_version do data = decompose_datetime(DateTime.to_naive(datetime)) ++ [datetime.time_zone] Encoder.encode({@datetime_with_zone_id_signature, data}, bolt_version) end defp do_call_encode( :datetime_with_tz_offset, %DateTimeWithTZOffset{naive_datetime: ndt, timezone_offset: tz_offset}, bolt_version ) when bolt_version >= 2 and bolt_version <= @last_version do data = decompose_datetime(ndt) ++ [tz_offset] Encoder.encode({@datetime_with_zone_offset_signature, data}, bolt_version) end defp do_call_encode(:duration, %Duration{} = duration, bolt_version) when bolt_version >= 2 and bolt_version <= @last_version do Encoder.encode({@duration_signature, compact_duration(duration)}, bolt_version) end defp do_call_encode(:point, %Point{z: nil} = point, bolt_version) when bolt_version >= 2 and bolt_version <= @last_version do Encoder.encode({@point2d_signature, [point.srid, point.x, point.y]}, bolt_version) end defp do_call_encode(:point, %Point{} = point, bolt_version) when bolt_version >= 2 and bolt_version <= @last_version do Encoder.encode( {@point3d_signature, [point.srid, point.x, point.y, point.z]}, bolt_version ) end end end end