Skip to content

Commit

Permalink
📎 more coercers
Browse files Browse the repository at this point in the history
  • Loading branch information
Aleksei Matiushkin committed Feb 25, 2024
1 parent ed5fa57 commit 3daa4e8
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ end
I suggest adding [`boundary`](https://hexdocs.pm/boundary) as a dependency since that is used in this project.

## Changelog
* `1.2.10` — more coercers
* `1.2.8` — `Estructura.Tree``Estructura.Aston` + `Aston.access/2` to retrieve and access key by names
* `1.2.5` — `use Estructura.Nested flattenable: boolean(), jason: boolean(), transformer: boolean()`
* `1.2.3` — Several `coerce/1` and `validate/1` clauses, default coercers
Expand Down
43 changes: 43 additions & 0 deletions lib/estructura/coercers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,25 @@ defmodule Estructura.Coercers.Integer do
def coerce(value) when is_float(value), do: {:ok, round(value)}
end

defmodule Estructura.Coercers.Float do
@moduledoc "Default coercer for `:float`, coercing strings and integers by multiplying by `1.0`"

@behaviour Estructura.Coercer
@impl Estructura.Coercer

def coerce(value) when is_integer(value), do: {:ok, 1.0 * value}

def coerce(value) when is_binary(value) do
case Float.parse(value) do
{float, ""} -> {:ok, float}
{_float, remainder} -> {:error, "Trailing garbage: ‹#{remainder}›"}
:error -> {:error, "Invalid value: ‹#{inspect(value)}›"}
end
end

def coerce(value) when is_float(value), do: {:ok, value}
end

defmodule Estructura.Coercers.Date do
@moduledoc "Default coercer for `:date`, coercing strings (_ISO8601_) and integers (_epoch_)"

Expand Down Expand Up @@ -58,6 +77,30 @@ defmodule Estructura.Coercers.Date do
end
end

defmodule Estructura.Coercers.Time do
@moduledoc "Default coercer for `:time`, coercing strings (_ISO8601_) and integers (_epoch_)"

@behaviour Estructura.Coercer
@impl Estructura.Coercer

def coerce(%Time{} = value), do: {:ok, value}
def coerce(%DateTime{} = value), do: {:ok, DateTime.to_time(value)}

def coerce(<<_::binary-size(2), ?:, _::binary-size(2), ?:, _::binary-size(2)>> = value),
do: Time.from_iso8601(value)

def coerce(<<y::binary-size(2), m::binary-size(2), d::binary-size(2)>>),
do: coerce(y <> <<?:>> <> m <> <<?:>> <> d)

def coerce(value) when is_binary(value) do
case DateTime.from_iso8601(value) do
{:ok, value, 0} -> {:ok, DateTime.to_time(value)}
{:ok, _value, offset} -> {:error, "Unsupported offset: ‹#{offset}›"}
error -> error
end
end
end

defmodule Estructura.Coercers.Datetime do
@moduledoc "Default coercer for `:datetime`, coercing strings (_ISO8601_) and integers (_epoch_)"

Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule Estructura.MixProject do
use Mix.Project

@app :estructura
@version "1.2.9"
@version "1.2.10"

def project do
[
Expand Down

0 comments on commit 3daa4e8

Please sign in to comment.