defprotocol Jsonrs.Encoder do
@moduledoc """
Protocol controlling how a value is encoded to JSON.
By default, structs are encoded as maps without the `:__struct__` key. If this
is sufficient for your use, you don't need to implement this protocol.
When implementing an encoding function, the goal is to turn your value into
something already capable of being encoded.
## Example
An implementation of this protocol for `Decimal` might look something like
defimpl Jsonrs.Encoder, for: Decimal do
def encode(value) do
Decimal.to_string(value)
end
end
Which will cause the Decimal to be encoded as its string representation
"""
@fallback_to_any true
@doc """
Converts `value` to a JSON-encodable type.
"""
def encode(value)
end
defimpl Jsonrs.Encoder, for: Map do
def encode(map), do: :maps.map(fn _, v -> Jsonrs.Encoder.encode(v) end, map)
end
defimpl Jsonrs.Encoder, for: List do
def encode(list), do: Enum.map(list, &Jsonrs.Encoder.encode/1)
end
defimpl Jsonrs.Encoder, for: Tuple do
def encode(tuple) do
tuple |> Tuple.to_list() |> Jsonrs.Encoder.encode()
end
end
defimpl Jsonrs.Encoder, for: [Date, Time, NaiveDateTime, DateTime] do
def encode(d), do: d |> @for.to_iso8601()
end
defimpl Jsonrs.Encoder, for: URI do
def encode(uri), do: URI.to_string(uri)
end
defimpl Jsonrs.Encoder, for: Any do
def encode(s) when is_struct(s), do: s |> Map.from_struct() |> Jsonrs.Encoder.encode()
def encode(any), do: any
end