@@ -2,47 +2,29 @@ defmodule OpenApiSpex.Cast.Enum do
22 @ moduledoc false
33 alias OpenApiSpex.Cast
44
5- def cast ( % Cast { schema: % { enum: [ ] } } = ctx ) do
6- Cast . error ( ctx , { :invalid_enum } )
7- end
8-
9- def cast ( % Cast { schema: % { enum: [ value | _ ] } , value: value } ) do
10- { :ok , value }
11- end
12-
13- # Special case: convert binary to atom enum
14- def cast ( ctx = % Cast { schema: schema = % { enum: [ atom_value | tail ] } , value: value } )
15- when is_binary ( value ) and is_atom ( atom_value ) do
16- if value == to_string ( atom_value ) do
17- { :ok , atom_value }
18- else
19- cast ( % { ctx | schema: % { schema | enum: tail } } )
5+ def cast ( ctx = % Cast { schema: % { enum: enum } , value: value } ) do
6+ case Enum . find ( enum , { :error , :invalid_enum } , & equivalent? ( & 1 , value ) ) do
7+ { :error , :invalid_enum } -> Cast . error ( ctx , { :invalid_enum } )
8+ found -> { :ok , found }
209 end
2110 end
2211
23- # Special case: convert string-keyed map to atom-keyed map enum
24- def cast ( ctx = % Cast { schema: schema = % { enum: [ enum_map = % { } | tail ] } , value: value = % { } } ) do
25- if maps_equivalent? ( value , enum_map ) do
26- { :ok , enum_map }
27- else
28- cast ( % { ctx | schema: % { schema | enum: tail } } )
29- end
30- end
12+ defp equivalent? ( x , x ) , do: true
3113
32- def cast ( ctx = % Cast { schema: schema = % { enum: [ _ | tail ] } } ) do
33- cast ( % { ctx | schema: % { schema | enum: tail } } )
14+ # Special case: atoms are equivalent to their stringified representation
15+ defp equivalent? ( left , right ) when is_atom ( left ) and is_binary ( right ) do
16+ to_string ( left ) == right
3417 end
3518
36- defp maps_equivalent? ( x , x ) , do: true
37-
3819 # an explicit schema should be used to cast to enum of structs
39- defp maps_equivalent? ( _left , % _struct { } ) , do: false
20+ defp equivalent? ( _x , % _struct { } ) , do: false
4021
41- defp maps_equivalent? ( left = % { } , right = % { } ) when map_size ( left ) == map_size ( right ) do
42- Enum . all? ( right , fn { k , v } ->
43- maps_equivalent? ( Map . get ( left , to_string ( k ) ) , v )
22+ # Special case: Atom-keyed maps are equivalent to their string-keyed representation
23+ defp equivalent? ( left , right ) when is_map ( left ) and is_map ( right ) do
24+ Enum . all? ( left , fn { k , v } ->
25+ equivalent? ( v , Map . get ( right , to_string ( k ) ) )
4426 end )
4527 end
4628
47- defp maps_equivalent ?( _left , _right ) , do: false
29+ defp equivalent ?( _left , _right ) , do: false
4830end
0 commit comments