defmodule Manganese.SerializationKit.Structs.UnityVector3 do @moduledoc """ A Unity vector3 value with `:x`, `:y`, and `:z` components. *Note that Unity structs are available in order to process the data in the API server, but most vector calculations occur in the environment simulation service.* This module can be used as an Ecto type for de/serialization when interacting with the database. """ alias Manganese.SerializationKit.Structs @type t :: %Structs.UnityVector3{ x: float, y: float, z: float } defstruct [ :x, :y, :z ] # Helpers @doc """ A vector3 with zero values for all components. """ @spec zero :: t def zero, do: %Structs.UnityVector3{ x: 0, y: 0, z: 0 } # Deserialization @doc """ Deserialize a vector3 from a map. """ @spec from_map(t_external) :: t def from_map(%{ "x" => x, "y" => y, "z" => z }) do %Structs.UnityVector3{ x: x, y: y, z: z } end @doc """ """ @spec from_tuple(t_internal) :: t def from_tuple({ x, y, z }) do %Structs.UnityVector3{ x: x, y: y, z: z } end # Serialization @type t_internal :: { float, float, float } @type t_external :: map @doc """ """ @spec to_map(t) :: t_external def to_map(%Structs.UnityVector3{ x: x, y: y, z: z }) do %{ "x" => x, "y" => y, "z" => z } end @doc """ """ @spec to_tuple(t) :: t_internal def to_tuple(%Structs.UnityVector3{ x: x, y: y, z: z }) do { x, y, z } end # Ecto type @behaviour Ecto.Type @doc """ The PostgreSQL composite type used to represent a vector3. """ @spec type :: :unity_vector3 def type, do: :unity_vector3 @doc false def cast(%Structs.UnityVector3{} = unity_vector3) do { :ok, unity_vector3 } end @doc false def cast({ _x, _y, _z } = tuple) do { :ok, from_tuple tuple } end @doc false def cast(nil) do { :ok, nil } end @doc false def cast(_), do: :error @doc false def load({ _x, _y, _z } = tuple) do { :ok, from_tuple tuple } end @doc false def dump(%Structs.UnityVector3{} = unity_vector3) do { :ok, to_tuple unity_vector3 } end end