Jason codiert Binärdateien in UUID in Elixir

Sep 22 2020

Ich versuche mir einen sauberen Weg zu überlegen, um den Jason Encoder für Binärdateien zu überschreiben, mit dem ich UUIDs aus Binärdateien herausziehen kann. Folgendes möchte ich theoretisch tun:

defimpl Jason.Encoder, for: BitString do
  def encode(binary, opts) when is_binary(binary) do
    with false <- String.valid?(binary),
    {:ok, uid} <- Ecto.UUID.cast(binary) do
      uid
    else
    _ -> Jason.Encode.string(binary, opts)
    end
  end

  def encode(bitstring, _opts) do
    raise Protocol.UndefinedError,
      protocol: @protocol,
      value: bitstring,
      description: "cannot encode a bitstring to JSON"
  end
end

Ich denke in Anlehnung an dieses Stackoverflow-Beispiel, außer ich denke, das Problem hier ist, dass native Typen wie BitString nicht überschrieben werden können.

Antworten

4 AdamMillerchip Sep 22 2020 at 16:30

Anstatt zu versuchen, das Protokoll für global zu überschreiben BitString, können Sie eine UUID in eine eigene Struktur einschließen und das Jason.EncoderProtokoll für diese Struktur implementieren :

defmodule JsonUUID do
  defstruct [:uuid]

  defimpl Jason.Encoder do
    def encode(%JsonUUID{uuid: uuid}, opts) when is_binary(uuid) do
      uuid
      |> Ecto.UUID.cast!()
      |> Jason.Encode.string(opts)
    end
  end
end

Prüfung:

Jason.encode!(%JsonUUID{uuid: Ecto.UUID.bingenerate()})
=> "\"8cbf3df9-8408-4ce3-ac44-980a0f7dc19b\""