Как реализовать строковый протокол для массива произвольного типа в Elixir? - PullRequest
0 голосов
/ 26 мая 2020

У меня есть настраиваемый тип, который соответствует настраиваемому типу Postgres. Приведенный ниже код является соответствующим кодом для того же

@typedoc """
Slot is composed of start time and end time.
"""

@type t :: %Slot{start_time: Time.t(), end_time: Time.t()}

@enforce_keys [:start_time, :end_time]
defstruct start_time: nil, end_time: nil

def new(start_time, end_time) when is_binary(start_time) and is_binary(end_time) do
 with {:ok, start_time} <- Time.from_iso8601(start_time),
      {:ok, end_time} <- Time.from_iso8601(end_time),
      {:ok, _} <- validate_start_time_before_end_time(start_time, end_time) do
   %Slot{start_time: start_time, end_time: end_time}
 else
   {:error, :invalid_slot} ->
     {:error, {ArgumentError, "start time should be before end time"}}

   {:error, :invalid_format} ->
     {:error, {ArgumentError, "start time or end time not valid time"}}
 end
end

def new(start_time, end_time) do
 %Slot{start_time: start_time, end_time: end_time}
end

defp validate_start_time_before_end_time(start_time, end_time) do
 if Time.compare(start_time, end_time) != :lt do
   {:error, :invalid_slot}
 else
   {:ok, nil}
 end
end

То, что я хотел бы, это protocol String.Chars, реализованный для массива таких настраиваемых типов. В документации по этому поводу не очень ясно.

1 Ответ

0 голосов
/ 26 мая 2020

Я не уверен, что именно неясно в документации, но is OSS .

defimpl String.Chars, for: Slot do
  def to_string(slot) do
    "start_time: #{slot.start_time}, end_time: #{slot.end_time}"
  end
end

Обычно мы используем индивидуальную реализацию для Inspect, но не для String.Chars.


Примечание: нет массива в Elixir core.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...