defmodule Postgrex.Extensions.Path do @moduledoc false import Postgrex.BinaryUtils, warn: false use Postgrex.BinaryExtension, send: "path_send" alias Postgrex.Extensions.Path alias Postgrex.Extensions.Point def encode(_) do quote location: :keep do %Postgrex.Path{open: o, points: ps} when is_list(ps) and is_boolean(o) -> open_byte = Path.open_to_byte(o) len = length(ps) encoded_points = Enum.reduce(ps, [], fn(p, acc) -> [acc | Point.encode_point(p, Postgrex.Path)] end) # 1 byte for open/closed flag, 4 for length, 16 for each point nbytes = 5 + 16 * len [<>, open_byte, <> | encoded_points] other -> raise ArgumentError, Postgrex.Utils.encode_msg(other, Postgrex.Path) end end def decode(_) do quote location: :keep do <> -> Path.decode_path(path_data) end end def decode_path(<>) do open = (o == 1) points = decode_points(point_data, []) %Postgrex.Path{open: open, points: points} end def open_to_byte(true), do: 1 def open_to_byte(false), do: 0 defp decode_points(<<>>, points), do: Enum.reverse(points) defp decode_points(<>, points) do decode_points(rest, [%Postgrex.Point{x: x, y: y} | points]) end end