@@ -167,9 +167,13 @@ defmodule Ash.Type.Range do
167167 def dump_to_native ( % Range { empty?: true } , _constraints ) , do: { :ok , Range . empty ( ) }
168168
169169 def dump_to_native ( % Range { lower: lower , upper: upper , bounds: bounds } , constraints ) do
170- with { :ok , lower } <- dump_bound ( lower , constraints ) ,
171- { :ok , upper } <- dump_bound ( upper , constraints ) do
172- { :ok , % Range { lower: lower , upper: upper , bounds: bounds } }
170+ if Range . valid_bounds? ( bounds ) do
171+ with { :ok , lower } <- dump_bound ( lower , constraints ) ,
172+ { :ok , upper } <- dump_bound ( upper , constraints ) do
173+ { :ok , % Range { lower: lower , upper: upper , bounds: bounds } }
174+ end
175+ else
176+ :error
173177 end
174178 end
175179
@@ -178,16 +182,24 @@ defmodule Ash.Type.Range do
178182 @ impl true
179183 def apply_constraints ( nil , _constraints ) , do: { :ok , nil }
180184
185+ def apply_constraints ( % Range { bounds: bounds } = range , constraints ) do
186+ if Range . valid_bounds? ( bounds ) do
187+ do_apply_constraints ( range , constraints )
188+ else
189+ { :error , message: "range bounds must be a valid bounds specifier" }
190+ end
191+ end
192+
181193 # An empty range is constructed, not mistyped, so it is refused rather than nulled.
182- def apply_constraints ( % Range { empty?: true } = range , constraints ) do
194+ defp do_apply_constraints ( % Range { empty?: true } = range , constraints ) do
183195 if Keyword . get ( constraints , :allow_empty? , false ) do
184196 { :ok , range }
185197 else
186198 { :error , message: "range must not be empty" }
187199 end
188200 end
189201
190- def apply_constraints ( % Range { lower: lower , upper: upper } = range , constraints ) do
202+ defp do_apply_constraints ( % Range { lower: lower , upper: upper } = range , constraints ) do
191203 type = constraints [ :inner_type ]
192204 inner = constraints [ :inner_constraints ] || [ ]
193205
@@ -198,7 +210,7 @@ defmodule Ash.Type.Range do
198210 :ok <- check_bound ( :lower , range , constraints [ :lower ] || [ ] ) ,
199211 :ok <- check_bound ( :upper , range , constraints [ :upper ] || [ ] ) do
200212 # Canonicalizing can empty a range, so the empty rule is applied to the result.
201- if range . empty? , do: apply_constraints ( range , constraints ) , else: { :ok , range }
213+ if range . empty? , do: do_apply_constraints ( range , constraints ) , else: { :ok , range }
202214 end
203215 end
204216
@@ -325,7 +337,9 @@ defmodule Ash.Type.Range do
325337 end
326338
327339 defp extract ( % Range { lower: lower , upper: upper , bounds: bounds , empty?: empty? } ) do
328- { :ok , lower , upper , normalize_bounds ( bounds ) , empty? }
340+ with { :ok , bounds } <- normalize_bounds ( bounds ) do
341+ { :ok , lower , upper , bounds , empty? }
342+ end
329343 end
330344
331345 defp extract ( { lower , upper } ) , do: { :ok , lower , upper , :"[)" , false }
@@ -335,13 +349,27 @@ defmodule Ash.Type.Range do
335349 upper = map [ :upper ] || map [ "upper" ]
336350 bounds = map [ :bounds ] || map [ "bounds" ] || :"[)"
337351 empty? = map [ :empty? ] || map [ "empty?" ] || false
338- { :ok , lower , upper , normalize_bounds ( bounds ) , empty? }
352+
353+ with { :ok , bounds } <- normalize_bounds ( bounds ) do
354+ { :ok , lower , upper , bounds , empty? }
355+ end
339356 end
340357
341358 defp extract ( _ ) , do: { :error , "is not a valid range" }
342359
343- defp normalize_bounds ( bounds ) when is_atom ( bounds ) , do: bounds
344- defp normalize_bounds ( bounds ) when is_binary ( bounds ) , do: String . to_existing_atom ( bounds )
360+ defp normalize_bounds ( bounds ) when is_atom ( bounds ) do
361+ if Range . valid_bounds? ( bounds ) , do: { :ok , bounds } , else: bounds_error ( )
362+ end
363+
364+ defp normalize_bounds ( bounds ) when is_binary ( bounds ) do
365+ normalize_bounds ( String . to_existing_atom ( bounds ) )
366+ rescue
367+ ArgumentError -> bounds_error ( )
368+ end
369+
370+ defp normalize_bounds ( _ ) , do: bounds_error ( )
371+
372+ defp bounds_error , do: { :error , "bounds is not a valid bounds specifier" }
345373
346374 defp cast_bound ( nil , _fun , _constraints ) , do: { :ok , nil }
347375
0 commit comments