-
-
Notifications
You must be signed in to change notification settings - Fork 206
/
builtins.ex
111 lines (87 loc) · 3.32 KB
/
builtins.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
defmodule Ash.Resource.Validation.Builtins do
@moduledoc """
Built in validations that are available to all resources
The functions in this module are imported by default in the validations section.
"""
alias Ash.Resource.Validation
@doc """
Validates that an attribute's value is in a given list
"""
def one_of(attribute, values) do
{Validation.OneOf, attribute: attribute, values: values}
end
@doc "Validates that an attribute is being changed"
def changing(field) do
{Validation.Changing, field: field}
end
@doc "Validates that a field or argument matches another field or argument"
def confirm(field, confirmation) do
{Validation.Confirm, [field: field, confirmation: confirmation]}
end
@doc "Validates that an attribute on the original record does not equal a specific value"
def attribute_does_not_equal(attribute, value) do
{Validation.AttributeDoesNotEqual, attribute: attribute, value: value}
end
@doc "Validates that an attribute on the original record equals a specific value"
def attribute_equals(attribute, value) do
{Validation.AttributeEquals, attribute: attribute, value: value}
end
@doc "Validates that an attribute on the original record meets the given length criteria"
def string_length(attribute, opts \\ []) do
{Validation.StringLength, Keyword.merge(opts, attribute: attribute)}
end
@doc "Validates that attribute meets the given criteria"
def compare(attribute, opts \\ []) do
{Validation.Compare, Keyword.merge(opts, attribute: attribute)}
end
@doc """
Validates that an attribute's value matches a given regex or string, using the provided error, message if not.
`String.match?/2` is used to determine if it matches.
"""
def match(attribute, match, message \\ nil) do
message = message || "must match #{match}"
{Validation.Match, attribute: attribute, match: match, message: message}
end
@doc """
Validates the presence of a list of attributes
If no options are provided, validates that they are all present.
#{Ash.OptionsHelpers.docs(Keyword.delete(Validation.Present.schema(), :attributes))}
"""
def present(attributes, opts \\ []) do
if opts == [] do
attributes = List.wrap(attributes)
{Validation.Present, attributes: attributes, exactly: Enum.count(attributes)}
else
opts = Keyword.put(opts, :attributes, List.wrap(attributes))
{Validation.Present, opts}
end
end
@doc """
Validates the absence of a list of attributes
If no options are provided, validates that they are all absent.
The docs behave the same as `present/2`, except they validate absence.
"""
def absent(attributes, opts \\ []) do
if opts == [] do
{Validation.Present, attributes: List.wrap(attributes), exactly: 0}
else
attributes = List.wrap(attributes)
count = Enum.count(attributes)
new_opts =
case Keyword.fetch(opts, :at_least) do
{:ok, value} ->
Keyword.put(opts, :at_most, count - value)
:error ->
Keyword.put(opts, :at_most, 0)
end
new_opts =
case Keyword.fetch(opts, :at_most) do
{:ok, value} ->
Keyword.put(new_opts, :at_least, count - value)
:error ->
Keyword.put(new_opts, :at_least, 0)
end
present(attributes, new_opts)
end
end
end