Skip to content

Elixir terms converter extensions #89

@ulissesalmeida

Description

@ulissesalmeida

Hi 👋

I would like to know if the maintainers are interested in a feature like this.

Let's say I have this message:

package MyApp.Proto;

message NaiveDateTime {
  uint32 microseconds = 1;
}

Then, when I working I'm my app, I've always to convert to an Elixir term.

message.birthday
%MyApp.Proto.NaiveDateTime{microseconds: ...}

# oh no, I have to remember to:
to_naive_date_time(message.birthday)
~N[1988-10-29 00:00:00]

I was wondering, wouldn't it be nice to have a way to tell the encoder/decoder how they work with some messages. Then, I could write in my app:

message.birthday
~N[2000-01-01 00:00:00]

I really would like to help to add this feature, but I would like to hear from you folks if you are interested.

Then, we can discuss the API and how this extension should work.

I had a suggestion, we could have something like:

message NaiveDateTime {
  option (elixirpb.message).converter = "MyApp.NaiveDateTimeConverter";
  uint32 microseconds = 1;
}

Then in my app, I implement some module behavior:

defmodule MyApp.NaiveDateTimeConverter do
  @behaviour Protobuf.Converter

  # or post_decode, decode, after_decode
  def to_elixir(%MyApp.Protobuff.NaiveDateTime{microseconds: microseconds}),
    do: NaiveDateTime.from_unix!(microseconds, :microsecond)

  # or pre_encode, encode, before_encode
  def to_protobuf(%DateTime{} = datetime) do
    microseconds = DateTime.to_unix(datetime, :microsecond)
    %MyApp.Protobuff.NaiveDateTime{microseconds: microseconds}
  end

  def to_protobuf(%NaiveDateTime{} = naive) do
    {:ok, datetime} = DateTime.from_naive(naive, "Etc/UTC")
    microseconds = DateTime.to_unix(datetime, :microsecond)
    %MyApp.Protobuff.NaiveDateTime{microseconds: microseconds}
  end

  def elixir_type, do: "NaiveDateTime.t() | DateTime.t()"
end

What do you folks think? Do we have space in this library for such a feature?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions