any_of field for structs is not behaving as expected
Closed this issue · 1 comments
flaviogrossi commented
Hi,
given the following example
defmodule Foo do
use Xema
xema do
field :value, :atom, const: :foo
end
end
defmodule Bar do
use Xema
xema do
field :value, :atom, const: :bar
end
end
defmodule FooBar do
use Xema
xema do
field :foobar, :any, one_of: [Foo, Bar]
end
end
With this definition, the following code fails
iex(1)> Foo.cast %{value: :foo}
{:ok, %Foo{value: :foo}}
iex(2)> Bar.cast %{value: :bar}
{:ok, %Bar{value: :bar}}
iex(3)> FooBar.cast %{foobar: %{value: :foo}}
** (Protocol.UndefinedError) protocol Xema.Castable not implemented for %Bar{value: :foo} of type Bar (a struct). This protocol is implemented for the following type(s): OtherRequest, OneRequest, Date, DateTime, Tuple, Time, Decimal, NaiveDateTime, BitString, Float, Integer, Map, List, Atom
(xema 0.13.10) lib/xema/castable.ex:1: Xema.Castable.impl_for!/1
(xema 0.13.10) lib/xema/castable.ex:9: Xema.Castable.cast/2
(xema 0.13.10) lib/xema.ex:755: Xema.castable_cast/2
(xema 0.13.10) lib/xema.ex:736: Xema.do_cast/4
(xema 0.13.10) lib/xema.ex:1079: anonymous fn/3 in Xema.do_cast_combiner/4
(elixir 1.11.4) lib/enum.ex:2193: Enum."-reduce/3-lists^foldl/2-0-"/3
(xema 0.13.10) lib/xema.ex:1078: Xema.do_cast_combiner/4
(xema 0.13.10) lib/xema.ex:834: anonymous fn/8 in Xema.cast_values/4
Implementing the castable protocol for both the structures, works only for one of the choices
iex(1)> FooBar.cast %{foobar: %{value: :bar}}
{:ok, %FooBar{foobar: %Bar{value: :bar}}}
iex(2)> FooBar.cast %{foobar: %{value: :foo}}
{:error,
%Xema.ValidationError{
message: nil,
reason: %{
properties: %{
foobar: %{
one_of: {:error,
[
%{module: Foo, value: %Bar{value: :foo}},
%{properties: %{value: %{const: :bar, value: :foo}}}
]},
value: %Bar{value: :foo}
}
}
}
}}
Thanks
NickNeck commented
Thanks for reporting. I will have a look.