Jason 在 Elixir 中将二进制编码为 UUID
Jason encode binary to UUID in Elixir
我正在尝试想出一种干净的方法来覆盖二进制文件的 JasonEncoder,这样我就可以从二进制文件中提取 UUID。这是我理论上想做的事情:
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
我按照 Whosebug 示例的思路思考,但我认为这里的问题是不能覆盖像 BitString 这样的原生类型。
与其尝试全局覆盖 BitString
的协议,不如将 UUID 包装在其自己的结构中,并为该结构实施 Jason.Encoder
协议:
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
测试:
Jason.encode!(%JsonUUID{uuid: Ecto.UUID.bingenerate()})
=> "\"8cbf3df9-8408-4ce3-ac44-980a0f7dc19b\""
我正在尝试想出一种干净的方法来覆盖二进制文件的 JasonEncoder,这样我就可以从二进制文件中提取 UUID。这是我理论上想做的事情:
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
我按照
与其尝试全局覆盖 BitString
的协议,不如将 UUID 包装在其自己的结构中,并为该结构实施 Jason.Encoder
协议:
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
测试:
Jason.encode!(%JsonUUID{uuid: Ecto.UUID.bingenerate()})
=> "\"8cbf3df9-8408-4ce3-ac44-980a0f7dc19b\""