safeshield 1.2.2__py3-none-any.whl → 1.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  from .base import ValidationRule
2
2
  from typing import Any, Dict, List, Optional, Set, Union, Tuple, Type
3
3
  from enum import Enum
4
+ from .basic import RequiredRule, ProhibitedRule, PresentRule, MissingRule, ExcludeRule
4
5
  import re
5
6
  import inspect
6
7
  from collections.abc import Iterable
@@ -9,7 +10,7 @@ from collections.abc import Iterable
9
10
  # CONDITIONAL VALIDATION RULES
10
11
  # =============================================
11
12
 
12
- class RequiredIfRule(ValidationRule):
13
+ class RequiredIfRule(RequiredRule):
13
14
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
14
15
  if len(params) < 2 or len(params) % 2 != 0:
15
16
  return True
@@ -22,30 +23,30 @@ class RequiredIfRule(ValidationRule):
22
23
  continue
23
24
 
24
25
  actual_value = self.get_field_value(other_field, '')
26
+
25
27
  if actual_value == expected_value:
26
28
  condition_met = True
27
29
  break
28
-
30
+
29
31
  if not condition_met:
30
32
  return True
31
-
32
- return not self.is_empty(value)
33
+
34
+ return super().validate(field, value, params)
33
35
 
34
- def message(self, field: str, params: List[str]) -> str:
35
- valid_conditions = []
36
- if len(params) >= 2 and len(params) % 2 == 0:
37
- valid_conditions = [
38
- f"{params[i]} = {params[i+1]}"
39
- for i in range(0, len(params), 2)
40
- if params[i] and params[i+1] is not None
41
- ]
36
+ class RequiredUnlessRule(RequiredRule):
37
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
38
+ if len(params) < 2:
39
+ return False
40
+
41
+ other_field, other_value = params[0], params[1]
42
+ actual_value = self.get_field_value(other_field, '')
42
43
 
43
- if not valid_conditions:
44
- return f"Invalid required_if rule configuration for {field}"
44
+ if actual_value == other_value:
45
+ return True
45
46
 
46
- return f"The :name field is required when any of these are true: {', '.join(valid_conditions)}"
47
+ return super().validate(field, value, params)
47
48
 
48
- class RequiredAllIfRule(ValidationRule):
49
+ class RequiredAllIfRule(RequiredRule):
49
50
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
50
51
  if len(params) < 2:
51
52
  return False
@@ -60,77 +61,9 @@ class RequiredAllIfRule(ValidationRule):
60
61
  if not all_conditions_met:
61
62
  return True
62
63
 
63
- return not self.is_empty(value)
64
-
65
- def message(self, field: str, params: List[str]) -> str:
66
- conditions = " AND ".join(f"{f} = {v}" for f, v in zip(params[::2], params[1::2]))
67
- return f"The :name field is required when ALL conditions are met: {conditions}"
68
-
69
- class RequiredUnlessRule(ValidationRule):
70
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
71
- if len(params) < 2:
72
- return False
73
-
74
- other_field, other_value = params[0], params[1]
75
- actual_value = self.get_field_value(other_field, '')
76
-
77
- if actual_value == other_value:
78
- return True
79
-
80
- return not self.is_empty(value)
81
-
82
- def message(self, field: str, params: List[str]) -> str:
83
- return f"The :name field is required unless {params[0]} is {params[1]}."
84
-
85
- class RequiredWithRule(ValidationRule):
86
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
87
- if not params:
88
- return False
89
-
90
- if any(f in self.validator.data for f in params):
91
- return not self.is_empty(value)
92
- return True
93
-
94
- def message(self, field: str, params: List[str]) -> str:
95
- return f"The :name field is required when {', '.join(params)} is present."
96
-
97
- class RequiredWithAllRule(ValidationRule):
98
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
99
- if not params:
100
- return False
101
-
102
- if all(f in self.validator.data for f in params):
103
- return not self.is_empty(value)
104
- return True
64
+ return super().validate(field, value, params)
105
65
 
106
- def message(self, field: str, params: List[str]) -> str:
107
- return f"The :name field is required when all of {', '.join(params)} are present."
108
-
109
- class RequiredWithoutRule(ValidationRule):
110
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
111
- if not params:
112
- return False
113
-
114
- if any(f not in self.validator.data for f in params):
115
- return not self.is_empty(value)
116
- return True
117
-
118
- def message(self, field: str, params: List[str]) -> str:
119
- return f"The :name field is required when {', '.join(params)} is not present."
120
-
121
- class RequiredWithoutAllRule(ValidationRule):
122
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
123
- if not params:
124
- return False
125
-
126
- if all(f not in self.validator.data for f in params):
127
- return not self.is_empty(value)
128
- return True
129
-
130
- def message(self, field: str, params: List[str]) -> str:
131
- return f"The :name field is required when none of {', '.join(params)} are present."
132
-
133
- class ProhibitedIfRule(ValidationRule):
66
+ class ProhibitedIfRule(ProhibitedRule):
134
67
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
135
68
  if len(params) < 2:
136
69
  return False
@@ -141,12 +74,9 @@ class ProhibitedIfRule(ValidationRule):
141
74
  if actual_value != other_value:
142
75
  return True
143
76
 
144
- return self.is_empty(value)
77
+ return super().validate(field, value, params)
145
78
 
146
- def message(self, field: str, params: List[str]) -> str:
147
- return f"The :name field is prohibited when {params[0]} is {params[1]}."
148
-
149
- class ProhibitedUnlessRule(ValidationRule):
79
+ class ProhibitedUnlessRule(ProhibitedRule):
150
80
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
151
81
  if len(params) < 2:
152
82
  return False
@@ -157,176 +87,79 @@ class ProhibitedUnlessRule(ValidationRule):
157
87
  if actual_value == other_value:
158
88
  return True
159
89
 
160
- return self.is_empty(value)
90
+ return super().validate(field, value, params)
161
91
 
162
- def message(self, field: str, params: List[str]) -> str:
163
- return f"The :name field is prohibited unless {params[0]} is {params[1]}."
164
-
165
- class FilledIfRule(ValidationRule):
92
+ class PresentIfRule(PresentRule):
166
93
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
167
94
  if len(params) < 2:
168
95
  return False
169
-
170
96
  other_field, other_value = params[0], params[1]
171
- actual_value = self.get_field_value(other_field, '')
172
97
 
173
- if actual_value != other_value:
174
- return True
175
-
176
- return value not in ('', None)
177
-
178
- def message(self, field: str, params: List[str]) -> str:
179
- return f"The :name field must be filled when {params[0]} is {params[1]}."
180
-
181
- class RegexRule(ValidationRule):
182
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
183
- if not params or not isinstance(value, str):
184
- return False
185
- try:
186
- return bool(re.fullmatch(params[0], value))
187
- except re.error:
188
- return False
189
-
190
- def message(self, field: str, params: List[str]) -> str:
191
- return f"The :name format is invalid."
192
-
193
- class NotRegexRule(ValidationRule):
194
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
195
- if not params or not isinstance(value, str):
196
- return True
197
- print(not bool(re.search(params[0], value)))
198
- try:
199
- return not bool(re.search(params[0], value))
200
- except re.error:
201
- return True
202
-
203
- def message(self, field: str, params: List[str]) -> str:
204
- return f"The :name format is invalid."
205
-
206
- class InRule(ValidationRule):
207
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
208
- allowed_values = self._parse_option_values(field, params)
209
- return (str(value) in allowed_values or value in allowed_values)
210
-
211
- def message(self, field: str, params: List[str]) -> str:
212
- allowed_values = self._parse_option_values(field, params)
213
- return f"The selected :name must be in : {', '.join(map(str, allowed_values))}"
214
-
215
- class NotInRule(ValidationRule):
216
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
217
- not_allowed_values = self._parse_option_values(field, params)
218
- return str(value) not in not_allowed_values
219
-
220
- def message(self, field: str, params: List[str]) -> str:
221
- not_allowed_values = self._parse_option_values(field, params)
222
- return f"The selected :name must be not in : {', '.join(map(str, not_allowed_values))}"
98
+ if self.get_field_value(other_field, None) == other_value:
99
+ return super().validate(field, value, params)
100
+ return True
223
101
 
224
- class EnumRule(ValidationRule):
225
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
226
- allowed_values = self._parse_option_values(field, params)
227
- return (str(value) in allowed_values or value in allowed_values)
228
-
229
- def message(self, field: str, params: List[str]) -> str:
230
- allowed_values = self._parse_option_values(field, params)
231
- return f"The :name must be one of: {', '.join(map(str, allowed_values))}"
232
-
233
- class UniqueRule(ValidationRule):
102
+ class PresentUnlessRule(PresentRule):
234
103
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
235
- if not params or not hasattr(self.validator, 'db_manager') or not self.validator.db_manager:
104
+ if len(params) < 2:
236
105
  return False
237
-
238
- table = params[0]
239
- column = field if len(params) == 1 else params[1]
106
+ other_field, other_value = params[0], params[1]
240
107
 
241
- try:
242
- # Optional: handle ignore case (id)
243
- ignore_id = None
244
- if len(params) > 2 and params[2].startswith('ignore:'):
245
- ignore_field = params[2].split(':')[1]
246
- ignore_id = self.get_field_value(ignore_field)
247
- return self.validator.db_manager.is_unique(table, column, value, ignore_id)
248
- except Exception as e:
249
- print(f"Database error in UniqueRule: {e}")
250
- return False
251
-
252
- def message(self, field: str, params: List[str]) -> str:
253
- return f"The :name has already been taken."
254
-
255
- class ExistsRule(ValidationRule):
256
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
257
- if not params or not hasattr(self.validator, 'db_manager') or not self.validator.db_manager:
258
- return False
259
-
260
- table = params[0]
261
- column = field if len(params) == 1 else params[1]
108
+ if self.get_field_value(other_field, None) != other_value:
109
+ return super().validate(field, value, params)
262
110
 
263
- try:
264
- return self.validator.db_manager.exists(table, column, value)
265
- except Exception as e:
266
- print(f"Database error in ExistsRule: {e}")
267
- return False
268
-
269
- def message(self, field: str, params: List[str]) -> str:
270
- return f"The selected :name is invalid."
271
-
272
- class ConfirmedRule(ValidationRule):
273
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
274
- confirmation_field = f"{field}_confirmation"
111
+ return True
275
112
 
276
- return value == self.get_field_value(confirmation_field, '')
277
-
278
- def message(self, field: str, params: List[str]) -> str:
279
- return f"The :name confirmation does not match."
280
-
281
- class SameRule(ValidationRule):
113
+ class MissingIfRule(MissingRule):
282
114
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
283
- if not params:
115
+ if len(params) < 2:
284
116
  return False
285
- return value == self.get_field_value(params[0])
117
+ other_field, other_value = params[0], params[1]
118
+
119
+ if self.get_field_value(other_field, None) == other_value:
120
+ return super().validate(field, value, params)
121
+
122
+ return True
286
123
 
287
- def message(self, field: str, params: List[str]) -> str:
288
- return f"The :name and {params[0]} must match."
289
-
290
- class DifferentRule(ValidationRule):
124
+ class MissingUnlessRule(MissingRule):
291
125
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
292
- if not params:
126
+ if len(params) < 2:
293
127
  return False
294
- return value != self.get_field_value(params[0])
295
-
296
- def message(self, field: str, params: List[str]) -> str:
297
- return f"The :name and {params[0]} must be different."
128
+ other_field, other_value = params[0], params[1]
129
+ if self.get_field_value(other_field, None) != other_value:
130
+ return super().validate(field, value, params)
298
131
 
299
- class AcceptedRule(ValidationRule):
300
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
301
- if isinstance(value, str):
302
- return value.lower() in ['yes', 'on', '1', 'true']
303
- if isinstance(value, int):
304
- return value == 1
305
- if isinstance(value, bool):
306
- return value
307
- return False
132
+ return True
308
133
 
309
- def message(self, field: str, params: List[str]) -> str:
310
- return f"The :name must be accepted."
311
-
312
- class DeclinedRule(ValidationRule):
134
+ class ExcludeIfRule(ExcludeRule):
313
135
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
314
- if isinstance(value, str):
315
- return value.lower() in ['no', 'off', '0', 'false']
316
- if isinstance(value, int):
317
- return value == 0
318
- if isinstance(value, bool):
319
- return not value
320
- return False
136
+ conditions = [(f.strip(), v.strip()) for f, v in zip(params[::2], params[1::2])]
137
+
138
+ all_conditions_met = all(
139
+ self.get_field_value(f) == v
140
+ for f, v in conditions
141
+ )
142
+
143
+ if all_conditions_met:
144
+ return super().validate(field, value, params)
145
+ return True
321
146
 
322
147
  def message(self, field: str, params: List[str]) -> str:
323
- return f"The :name must be declined."
324
-
148
+ return f"The :attribute field is excluded when {params[0]} is {params[1]}."
325
149
 
326
- class BailRule(ValidationRule):
150
+ class ExcludeUnlessRule(ExcludeRule):
327
151
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
328
- self.validator._stop_on_first_failure = True
152
+ conditions = [(f.strip(), v.strip()) for f, v in zip(params[::2], params[1::2])]
153
+
154
+ all_conditions_met = all(
155
+ self.get_field_value(f) == v
156
+ for f, v in conditions
157
+ )
158
+
159
+ if not all_conditions_met:
160
+ return super().validate(field, value, params)
161
+
329
162
  return True
330
-
163
+
331
164
  def message(self, field: str, params: List[str]) -> str:
332
- return ""
165
+ return f"The :attribute field is excluded unless {params[0]} is {params[1]}."
validator/rules/date.py CHANGED
@@ -15,7 +15,7 @@ class DateRule(ValidationRule):
15
15
  return False
16
16
 
17
17
  def message(self, field: str, params: List[str]) -> str:
18
- return f"The :name is not a valid date."
18
+ return f"The :attribute is not a valid date."
19
19
 
20
20
  class DateEqualsRule(ValidationRule):
21
21
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -35,7 +35,7 @@ class DateEqualsRule(ValidationRule):
35
35
  return False
36
36
 
37
37
  def message(self, field: str, params: List[str]) -> str:
38
- return f"The :name must be equal to {params[0]}."
38
+ return f"The :attribute must be equal to {params[0]}."
39
39
 
40
40
  class AfterRule(ValidationRule):
41
41
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -61,7 +61,7 @@ class AfterRule(ValidationRule):
61
61
  return False
62
62
 
63
63
  def message(self, field: str, params: List[str]) -> str:
64
- return f"The :name must be after {params[0]}"
64
+ return f"The :attribute must be after {params[0]}"
65
65
 
66
66
  class AfterOrEqualRule(ValidationRule):
67
67
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -85,7 +85,7 @@ class AfterOrEqualRule(ValidationRule):
85
85
  return False
86
86
 
87
87
  def message(self, field: str, params: List[str]) -> str:
88
- return f"The :name must be after or equal to {params[0]}"
88
+ return f"The :attribute must be after or equal to {params[0]}"
89
89
 
90
90
  class BeforeRule(ValidationRule):
91
91
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -111,7 +111,7 @@ class BeforeRule(ValidationRule):
111
111
  return False
112
112
 
113
113
  def message(self, field: str, params: List[str]) -> str:
114
- return f"The :name must be before {params[0]}"
114
+ return f"The :attribute must be before {params[0]}"
115
115
 
116
116
  class BeforeOrEqualRule(ValidationRule):
117
117
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -137,7 +137,7 @@ class BeforeOrEqualRule(ValidationRule):
137
137
  return False
138
138
 
139
139
  def message(self, field: str, params: List[str]) -> str:
140
- return f"The :name must be before or equal to {params[0]}"
140
+ return f"The :attribute must be before or equal to {params[0]}"
141
141
 
142
142
  class DateFormatRule(ValidationRule):
143
143
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -151,4 +151,4 @@ class DateFormatRule(ValidationRule):
151
151
  return False
152
152
 
153
153
  def message(self, field: str, params: List[str]) -> str:
154
- return f"The :name must match the format {params[0]}"
154
+ return f"The :attribute must match the format {params[0]}"
validator/rules/files.py CHANGED
@@ -28,7 +28,7 @@ class FileRule(ValidationRule):
28
28
  return False
29
29
 
30
30
  def message(self, field: str, params: List[str]) -> str:
31
- return f"The {field} must be a valid file"
31
+ return f"The :attribute must be a valid file"
32
32
 
33
33
  class DimensionsRule(ValidationRule):
34
34
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -99,7 +99,7 @@ class DimensionsRule(ValidationRule):
99
99
  if max_rules:
100
100
  messages.append(f"maximum {max_rules[0][4:]}")
101
101
 
102
- return f"Image {field} dimensions must be {' and '.join(messages)}"
102
+ return f"Image :attribute dimensions must be {' and '.join(messages)}"
103
103
 
104
104
  class ExtensionsRule(ValidationRule):
105
105
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -118,7 +118,7 @@ class ExtensionsRule(ValidationRule):
118
118
  return ext in [e.lower().strip() for e in params]
119
119
 
120
120
  def message(self, field: str, params: List[str]) -> str:
121
- return f"File {field} must have one of these extensions: {', '.join(params)}"
121
+ return f"File :attribute must have one of these extensions: {', '.join(params)}"
122
122
 
123
123
  class ImageRule(ValidationRule):
124
124
  VALID_EXTENSIONS = {'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'}
@@ -146,7 +146,7 @@ class ImageRule(ValidationRule):
146
146
  return True
147
147
 
148
148
  def message(self, field: str, params: List[str]) -> str:
149
- return f"The {field} must be a valid image file (JPEG, PNG, GIF, BMP, or WebP)"
149
+ return f"The :attribute must be a valid image file (JPEG, PNG, GIF, BMP, or WebP)"
150
150
 
151
151
  class MimeTypesRule(ValidationRule):
152
152
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -164,4 +164,4 @@ class MimeTypesRule(ValidationRule):
164
164
  return False
165
165
 
166
166
  def message(self, field: str, params: List[str]) -> str:
167
- return f"File {field} must be one of these types: {', '.join(params)}"
167
+ return f"File :attribute must be one of these types: {', '.join(params)}"
validator/rules/format.py CHANGED
@@ -17,7 +17,7 @@ class EmailRule(ValidationRule):
17
17
  return bool(re.match(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$", value))
18
18
 
19
19
  def message(self, field: str, params: List[str]) -> str:
20
- return f"The :name must be a valid email address."
20
+ return f"The :attribute must be a valid email address."
21
21
 
22
22
  class UrlRule(ValidationRule):
23
23
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -32,7 +32,7 @@ class UrlRule(ValidationRule):
32
32
  ))
33
33
 
34
34
  def message(self, field: str, params: List[str]) -> str:
35
- return f"The :name must be a valid URL."
35
+ return f"The :attribute must be a valid URL."
36
36
 
37
37
  class JsonRule(ValidationRule):
38
38
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -45,7 +45,7 @@ class JsonRule(ValidationRule):
45
45
  return False
46
46
 
47
47
  def message(self, field: str, params: List[str]) -> str:
48
- return f"The :name must be a valid JSON string."
48
+ return f"The :attribute must be a valid JSON string."
49
49
 
50
50
  class UuidRule(ValidationRule):
51
51
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -58,7 +58,7 @@ class UuidRule(ValidationRule):
58
58
  return False
59
59
 
60
60
  def message(self, field: str, params: List[str]) -> str:
61
- return f"The :name must be a valid UUID."
61
+ return f"The :attribute must be a valid UUID."
62
62
 
63
63
  class UlidRule(ValidationRule):
64
64
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -67,7 +67,7 @@ class UlidRule(ValidationRule):
67
67
  return bool(re.match(r'^[0-9A-HJKMNP-TV-Z]{26}$', value))
68
68
 
69
69
  def message(self, field: str, params: List[str]) -> str:
70
- return f"The :name must be a valid ULID."
70
+ return f"The :attribute must be a valid ULID."
71
71
 
72
72
  class IpRule(ValidationRule):
73
73
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -80,7 +80,7 @@ class IpRule(ValidationRule):
80
80
  return False
81
81
 
82
82
  def message(self, field: str, params: List[str]) -> str:
83
- return f"The :name must be a valid IP address."
83
+ return f"The :attribute must be a valid IP address."
84
84
 
85
85
  class TimezoneRule(ValidationRule):
86
86
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -93,7 +93,7 @@ class TimezoneRule(ValidationRule):
93
93
  return False
94
94
 
95
95
  def message(self, field: str, params: List[str]) -> str:
96
- return f"The :name must be a valid timezone."
96
+ return f"The :attribute must be a valid timezone."
97
97
 
98
98
  class HexRule(ValidationRule):
99
99
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -102,4 +102,4 @@ class HexRule(ValidationRule):
102
102
  return bool(re.match(r'^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$', value))
103
103
 
104
104
  def message(self, field: str, params: List[str]) -> str:
105
- return f"The :name must be a valid hexadecimal color code."
105
+ return f"The :attribute must be a valid hexadecimal color code."
validator/rules/string.py CHANGED
@@ -6,54 +6,47 @@ import re
6
6
  # STRING VALIDATION RULES
7
7
  # =============================================
8
8
 
9
- class StringRule(ValidationRule):
10
- def validate(self, field: str, value: Any, params: List[str]) -> bool:
11
- return isinstance(value, str)
12
-
13
- def message(self, field: str, params: List[str]) -> str:
14
- return f"The :name must be a string."
15
-
16
9
  class AlphaRule(ValidationRule):
17
10
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
18
11
  return isinstance(value, str) and value.isalpha()
19
12
 
20
13
  def message(self, field: str, params: List[str]) -> str:
21
- return f"The :name may only contain letters."
14
+ return f"The :attribute may only contain letters."
22
15
 
23
16
  class AlphaDashRule(ValidationRule):
24
17
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
25
18
  return isinstance(value, str) and bool(re.match(r'^[a-zA-Z0-9_-]+$', value))
26
19
 
27
20
  def message(self, field: str, params: List[str]) -> str:
28
- return f"The :name may only contain letters, numbers, dashes and underscores."
21
+ return f"The :attribute may only contain letters, numbers, dashes and underscores."
29
22
 
30
23
  class AlphaNumRule(ValidationRule):
31
24
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
32
25
  return isinstance(value, str) and value.isalnum()
33
26
 
34
27
  def message(self, field: str, params: List[str]) -> str:
35
- return f"The :name may only contain letters and numbers."
28
+ return f"The :attribute may only contain letters and numbers."
36
29
 
37
30
  class UppercaseRule(ValidationRule):
38
31
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
39
32
  return isinstance(value, str) and value == value.upper()
40
33
 
41
34
  def message(self, field: str, params: List[str]) -> str:
42
- return f"The :name must be uppercase."
35
+ return f"The :attribute must be uppercase."
43
36
 
44
37
  class LowercaseRule(ValidationRule):
45
38
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
46
39
  return isinstance(value, str) and value == value.lower()
47
40
 
48
41
  def message(self, field: str, params: List[str]) -> str:
49
- return f"The :name must be lowercase."
42
+ return f"The :attribute must be lowercase."
50
43
 
51
44
  class AsciiRule(ValidationRule):
52
45
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
53
46
  return isinstance(value, str) and all(ord(c) < 128 for c in value)
54
47
 
55
48
  def message(self, field: str, params: List[str]) -> str:
56
- return f"The :name must only contain ASCII characters."
49
+ return f"The :attribute must only contain ASCII characters."
57
50
 
58
51
  class StartsWithRule(ValidationRule):
59
52
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -62,7 +55,7 @@ class StartsWithRule(ValidationRule):
62
55
  return any(value.startswith(p) for p in params)
63
56
 
64
57
  def message(self, field: str, params: List[str]) -> str:
65
- return f"The :name must start with one of the following: {', '.join(params)}."
58
+ return f"The :attribute must start with one of the following: {', '.join(params)}."
66
59
 
67
60
  class EndsWithRule(ValidationRule):
68
61
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -71,4 +64,4 @@ class EndsWithRule(ValidationRule):
71
64
  return any(value.endswith(p) for p in params)
72
65
 
73
66
  def message(self, field: str, params: List[str]) -> str:
74
- return f"The :name must end with one of the following: {', '.join(params)}."
67
+ return f"The :attribute must end with one of the following: {', '.join(params)}."
validator/rules/type.py CHANGED
@@ -6,6 +6,13 @@ from datetime import datetime
6
6
  # TYPE DATA VALIDATION RULES
7
7
  # =============================================
8
8
 
9
+ class StringRule(ValidationRule):
10
+ def validate(self, field: str, value: Any, params: List[str]) -> bool:
11
+ return isinstance(value, str)
12
+
13
+ def message(self, field: str, params: List[str]) -> str:
14
+ return f"The :attribute must be a string."
15
+
9
16
  class NumericRule(ValidationRule):
10
17
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
11
18
  if isinstance(value, (int, float)):
@@ -15,7 +22,7 @@ class NumericRule(ValidationRule):
15
22
  return value.replace('.', '', 1).isdigit()
16
23
 
17
24
  def message(self, field: str, params: List[str]) -> str:
18
- return f"The :name must be a number."
25
+ return f"The :attribute must be a number."
19
26
 
20
27
  class IntegerRule(ValidationRule):
21
28
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -26,7 +33,7 @@ class IntegerRule(ValidationRule):
26
33
  return value.isdigit()
27
34
 
28
35
  def message(self, field: str, params: List[str]) -> str:
29
- return f"The :name must be an integer."
36
+ return f"The :attribute must be an integer."
30
37
 
31
38
  class BooleanRule(ValidationRule):
32
39
  def validate(self, field: str, value: Any, params: List[str]) -> bool:
@@ -39,4 +46,4 @@ class BooleanRule(ValidationRule):
39
46
  return False
40
47
 
41
48
  def message(self, field: str, params: List[str]) -> str:
42
- return f"The :name field must be true or false."
49
+ return f"The :attribute field must be true or false."